From 0780c1932253942fb5b61d0ec37dcddcf2d369d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Mon, 29 Apr 2024 17:56:41 +0200 Subject: [PATCH 001/104] Add explicit children types (#181257) ## Summary Prep work for React@18 bump tl;dr In React@18 `React.FC` doesn't contain `children` anymore, so in order to make the bump easier I have decided to split the effort in multiple faces and hopefully this will make it easier for everyone This PR focuses only on adding explicit `children` declaration either by using `React.PropsWithChildren` type or by adding `children: React.ReactNode` to the existing props types https://github.com/DefinitelyTyped/DefinitelyTyped/issues/46691 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Sergi Massaneda Co-authored-by: Marco Vettorello Co-authored-by: James Gowdy --- .../public/components/page/index.tsx | 8 +- .../app/pages/page_count_until/index.tsx | 5 +- .../app/pages/page_double_integers/index.tsx | 5 +- .../public/components/page.tsx | 5 +- .../public/common/example_page.tsx | 4 +- .../public/common/example_page.tsx | 4 +- .../public/panel_with_code_block.tsx | 4 +- .../cloud/deployment_details/services.tsx | 11 ++- .../content_editor/src/services.tsx | 14 ++-- .../table_list_view_table/src/services.tsx | 14 ++-- .../src/ui/project/navigation.tsx | 8 +- .../src/i18n_context_mock.tsx | 5 +- .../src/app_containers.tsx | 10 ++- .../src/core_theme_provider.tsx | 4 +- .../home/sample_data_card/src/services.tsx | 9 ++- .../home/sample_data_tab/src/services.tsx | 14 ++-- .../maintenance_window_callout/index.test.tsx | 6 +- .../src/context/cell_actions_context.test.tsx | 4 +- packages/kbn-cell-actions/src/types.ts | 10 ++- .../customizable_palette.stories.tsx | 4 +- .../src/drop_overlay_wrapper.tsx | 4 +- packages/kbn-i18n-react/src/provider.tsx | 4 +- .../settings/application/services.tsx | 11 ++- .../components/field_input/services.tsx | 9 ++- .../components/field_row/services.tsx | 4 +- .../settings/components/form/services.tsx | 7 +- packages/kbn-reporting/public/context.tsx | 12 +-- .../components/overview_panel.tsx | 4 +- .../components/select_client.tsx | 5 +- .../configuration/connector_configuration.tsx | 7 +- .../scheduling/connector_scheduling.tsx | 8 +- .../components/sync_jobs/flyout_panel.tsx | 5 +- .../src/dynamic/test_component.tsx | 15 ++-- .../compare_documents/comparison_controls.tsx | 12 +-- .../src/components/data_table_footer.tsx | 6 +- .../src/components/field_list/field_list.tsx | 4 +- .../src/services.tsx | 9 ++- .../kibana_context/render/render_provider.tsx | 9 +-- .../kibana_context/root/eui_provider.tsx | 4 +- .../kibana_context/root/root_provider.tsx | 4 +- .../react/kibana_mount/mount_point_portal.tsx | 8 +- .../project_switcher/src/services.tsx | 9 ++- .../button/exit_full_screen/src/services.tsx | 11 ++- .../card/no_data/impl/src/services.tsx | 9 ++- .../chrome/navigation/src/services.tsx | 9 ++- .../src/ui/components/panel/context.tsx | 16 +++- .../mocks/src/storybook_template.tsx | 4 +- .../src/services/error_boundary_services.tsx | 19 +++-- .../src/ui/error_boundary.test.tsx | 4 +- packages/shared-ux/file/context/src/index.tsx | 5 +- .../file/file_picker/impl/src/context.tsx | 4 +- .../link/redirect_app/impl/src/services.tsx | 11 ++- .../analytics_no_data/impl/src/services.tsx | 11 ++- .../page/kibana_no_data/impl/src/services.tsx | 11 ++- .../kibana_template/impl/src/services.tsx | 11 ++- .../page/no_data/impl/src/services.tsx | 9 ++- .../page/no_data_config/impl/src/services.tsx | 11 ++- .../no_data_views/impl/src/services.tsx | 11 ++- .../mosaic_vis_renderer.stories.tsx | 4 +- .../__stories__/pie_vis_renderer.stories.tsx | 4 +- .../treemap_vis_renderer.stories.tsx | 4 +- .../waffle_vis_renderer.stories.tsx | 4 +- .../content_client/content_client_context.tsx | 11 +-- .../content_client_mutation_hooks.test.tsx | 4 +- .../content_client_query_hooks.test.tsx | 4 +- .../custom_integrations/public/mocks.tsx | 4 +- .../custom_integrations/public/plugin.tsx | 4 +- .../public/services/index.tsx | 9 +-- .../custom_integrations/public/types.ts | 5 +- .../dashboard_listing.test.tsx | 4 +- .../flyout_panels/flyout_panels.tsx | 4 +- .../flyout_panels/flyout_panels_content.tsx | 4 +- .../components/field_editor_context.tsx | 10 ++- .../flyout_panels/flyout_panels.tsx | 1 + .../flyout_panels/flyout_panels_content.tsx | 2 +- .../preview/field_preview_context.tsx | 12 +-- .../index_header/index_header.tsx | 4 +- .../context/context_app_content.tsx | 4 +- .../saved_search_embeddable_base.tsx | 4 +- .../global_flyout/global_flyout.tsx | 4 +- .../components/page_loading/page_loading.tsx | 4 +- .../__stories__/form_global_fields.tsx | 6 +- .../components/__stories__/form_utils.tsx | 4 +- .../files_management/public/context.tsx | 4 +- .../interactive_setup/public/plugin.tsx | 4 +- .../public/text_truncate.tsx | 4 +- .../public/use_verification.tsx | 6 +- .../kibana_react/public/context/context.tsx | 8 +- .../kibana_react/public/context/types.ts | 4 +- .../public/theme/kibana_theme_provider.tsx | 11 ++- .../public/services/create/provider.tsx | 4 +- .../public/services/create/registry.tsx | 4 +- src/plugins/presentation_util/public/types.ts | 3 +- .../show_saved_object_save_modal.tsx | 4 +- .../management_section/mount_section.tsx | 4 +- .../button_submit/button_submit.tsx | 8 +- .../drilldown_form/drilldown_form.tsx | 4 +- .../components/flyout_frame/flyout_frame.tsx | 4 +- .../text_with_icon/text_with_icon.tsx | 4 +- .../trigger_line_item/trigger_line_item.tsx | 4 +- .../containers/context/context.tsx | 9 +-- .../drilldown_manager_footer.tsx | 4 +- .../drilldown_manager_title.tsx | 2 +- .../usage_collection/public/plugin.tsx | 4 +- .../public/components/page.tsx | 1 + .../public/components/page/index.tsx | 1 + .../public/components/section/section.tsx | 1 + .../log_rate_analysis_state_provider.tsx | 5 +- .../progress_controls/progress_controls.tsx | 4 +- .../components/date_picker_wrapper.test.tsx | 5 +- .../src/hooks/use_date_picker_context.tsx | 4 +- .../packages/ml/url_state/src/url_state.tsx | 3 +- .../data_quality_context/index.test.tsx | 4 +- .../data_quality_context/index.tsx | 3 +- .../data_quality/use_mappings/index.test.tsx | 4 +- .../data_quality/use_stats/index.test.tsx | 6 +- .../use_unallowed_values/index.test.tsx | 4 +- .../navigation/src/__mocks__/context.tsx | 3 +- .../navigation/src/context.tsx | 8 +- .../src/landing_links/landing_links_icons.tsx | 78 +++++++++---------- .../src/telemetry/telemetry_context.tsx | 7 +- .../change_point_detection_context.tsx | 8 +- .../change_point_detection/fields_config.tsx | 8 +- .../category_table/expanded_row.tsx | 4 +- .../log_categorization/format_category.tsx | 4 +- .../public/hooks/use_aiops_app_context.ts | 16 ++-- .../aiops/public/hooks/use_data_source.tsx | 4 +- .../aiops/public/hooks/use_filters_query.tsx | 19 +++-- .../plugins/aiops/public/hooks/use_reload.tsx | 10 ++- .../aiops/public/shared_lazy_components.tsx | 4 +- .../alerting/public/lib/test_utils.tsx | 6 +- .../custom_recurring_schedule.test.tsx | 4 +- .../recurring_schedule.test.tsx | 4 +- .../components/submit_button.test.tsx | 4 +- .../my_workpads/upload_dropzone.component.tsx | 8 +- .../home/my_workpads/upload_dropzone.tsx | 4 +- .../hooks/use_autoplay_helper.test.tsx | 4 +- .../workpad/hooks/use_refresh_helper.test.tsx | 8 +- .../workpad/workpad_presentation_helper.tsx | 4 +- .../public/routes/workpad/workpad_route.tsx | 6 +- .../workpad/workpad_routing_context.tsx | 4 +- .../public/client/ui/get_cases_context.tsx | 13 ++-- .../cases/public/common/test_utils.tsx | 4 +- ..._cases_add_to_existing_case_modal.test.tsx | 3 +- .../public/components/cases_context/index.tsx | 9 ++- .../components/connectors/test_utils.tsx | 3 +- .../components/create/assignees.test.tsx | 3 +- .../components/create/category.test.tsx | 3 +- .../components/create/connector.test.tsx | 3 +- .../use_cases_add_to_new_case_flyout.test.tsx | 3 +- .../public/components/create/form.test.tsx | 10 ++- .../create/sync_alerts_toggle.test.tsx | 3 +- .../public/components/create/tags.test.tsx | 3 +- .../public/components/create/title.test.tsx | 3 +- .../components/timeline_context/index.tsx | 9 ++- .../use_user_actions_handler.test.tsx | 3 +- .../actions/__mocks__/action_wrapper.tsx | 5 +- .../actions/add_to_existing_case.test.tsx | 5 +- .../public/containers/use_get_case.test.tsx | 3 +- .../containers/use_get_case_metrics.test.tsx | 3 +- .../cases/public/mocks/mock_cases_context.tsx | 4 +- x-pack/plugins/cases/public/types.ts | 4 +- x-pack/plugins/cloud/public/mocks.tsx | 4 +- x-pack/plugins/cloud/public/plugin.tsx | 6 +- x-pack/plugins/cloud/public/types.ts | 4 +- .../public/components/loading_state/index.tsx | 11 +-- .../public/test/test_provider.tsx | 4 +- .../cloud_chat/.storybook/decorator.tsx | 4 +- .../public/components/chat/when_idle.tsx | 4 +- .../cloud_chat/public/plugin.tsx | 4 +- .../cloud_chat/public/services/index.tsx | 9 ++- .../public/components/chart_panel.tsx | 5 +- .../additional_controls.tsx | 4 +- .../public/components/csp_loading_state.tsx | 11 +-- .../pages/rules/rules_container.test.tsx | 4 +- .../public/test/test_provider.tsx | 1 + .../auto_follow_pattern_delete_provider.d.ts | 4 +- .../file_data_visualizer.tsx | 4 +- .../lazy_load_bundle/component_wrapper.tsx | 4 +- .../ai_search_guide_accordion.tsx | 4 +- .../components/analytics/analytics_layout.tsx | 4 +- .../components/analytics_section.tsx | 9 ++- .../api_logs/api_log/api_log_flyout.tsx | 4 +- .../summary_section.tsx | 4 +- .../empty_search_applications_prompt.tsx | 4 +- .../connector/connector_scheduling.tsx | 8 +- .../sync_rules/connector_sync_form.tsx | 4 +- .../sync_rules/edit_sync_rules_tab.tsx | 12 +-- .../ml_inference/inference_config.tsx | 4 +- .../public/applications/index.tsx | 4 +- .../shared/flash_messages/flash_messages.tsx | 4 +- .../shared/layout/endpoints_header_action.tsx | 5 +- .../personal_dashboard_layout.tsx | 4 +- .../fleet/.storybook/context/index.tsx | 8 +- .../fleet/public/applications/fleet/app.tsx | 3 +- .../applications/fleet/layouts/error.tsx | 8 +- .../add_first_integration_splash.tsx | 4 +- .../components/page_steps/add_integration.tsx | 2 +- .../single_page_layout/components/layout.tsx | 1 + .../agent_details_integration.tsx | 1 + .../components/agent_status_filter.tsx | 1 + .../es_requirements_page.tsx | 8 +- .../error_pages/components/no_data_layout.tsx | 1 + .../settings/hooks/use_confirm_modal.tsx | 4 +- .../public/applications/integrations/app.tsx | 1 + .../components/header/header_portal.tsx | 1 + .../hooks/use_agent_policy_context.tsx | 4 +- .../hooks/use_integrations_state.tsx | 4 +- .../applications/integrations/index.tsx | 2 +- .../epm/components/package_list_grid/grid.tsx | 1 + .../screens/detail/overview/requirements.tsx | 2 +- .../public/components/extension_wrapper.tsx | 16 ++-- .../fleet/public/hooks/use_fleet_status.tsx | 1 + .../fleet/public/hooks/use_flyout_context.tsx | 4 +- .../public/mock/create_test_renderer.tsx | 8 +- .../public/components/result_tag_list.tsx | 2 +- .../components/phases/phase/phase.tsx | 1 + .../edit_policy/form/components/form.tsx | 1 + .../form/configuration_context.tsx | 4 +- .../edit_policy/form/form_errors_context.tsx | 4 +- .../form/global_fields_context.tsx | 4 +- .../form/phase_timings_context.tsx | 4 +- .../component_template_list/auth_provider.tsx | 6 +- .../with_privileges.tsx | 6 +- .../enrich_policies/auth_provider.tsx | 6 +- .../enrich_policies/with_privileges.tsx | 6 +- .../fields/edit_field/edit_field.tsx | 6 +- .../mappings_editor_context.tsx | 2 +- .../mappings_state_context.tsx | 2 +- .../public/application/index.tsx | 1 + .../context/processors_context.tsx | 1 + .../lens/public/app_plugin/app.test.tsx | 6 +- .../lens/public/app_plugin/mounter.tsx | 4 +- .../plugins/lens/public/mocks/store_mocks.tsx | 20 ++--- .../shared_components/toolbar_popover.tsx | 4 +- .../public/lists/mocks/query_wrapper.tsx | 2 +- x-pack/plugins/maps/public/render_app.tsx | 2 +- .../public/apps/common_providers.tsx | 1 + .../test_utils/use_global_storybook_theme.tsx | 8 +- .../plugins/ml/common/types/storage.test.tsx | 2 +- .../collapsible_panel/collapsible_panel.tsx | 2 +- .../field_stats_flyout_provider.tsx | 1 + .../components/help_popover/help_popover.tsx | 1 + .../components/page_header/page_header.tsx | 4 +- .../contexts/ml/data_source_context.tsx | 2 +- .../contexts/ml/ml_notifications_context.tsx | 4 +- .../contexts/ml/serverless_context.tsx | 1 + .../components/details_step/description.tsx | 4 +- .../explorer/alerts/swim_lane_wrapper.tsx | 1 + .../explorer/anomaly_explorer_context.tsx | 4 +- .../public/application/explorer/explorer.tsx | 1 + .../loading_wrapper/loading_wrapper.tsx | 1 + .../common/model_memory_limit/description.tsx | 1 + .../components/data_view/description.tsx | 3 +- .../components/frequency/description.tsx | 1 + .../components/query/description.tsx | 3 +- .../components/query_delay/description.tsx | 1 + .../components/scroll_size/description.tsx | 1 + .../components/time_field/description.tsx | 3 +- .../components/calendars/description.tsx | 3 +- .../components/custom_urls/description.tsx | 3 +- .../components/annotations/description.tsx | 3 +- .../dedicated_index/description.tsx | 3 +- .../ignore_unavailable/description.tsx | 3 +- .../components/model_plot/description.tsx | 3 +- .../components/groups/description.tsx | 1 + .../job_description/description.tsx | 3 +- .../components/job_id/description.tsx | 1 + .../advanced_detector_modal/descriptions.tsx | 16 ++-- .../advanced_detector_modal/function_help.tsx | 3 +- .../advanced_detector_modal/modal_wrapper.tsx | 9 ++- .../components/bucket_span/description.tsx | 4 +- .../categorization_field/description.tsx | 4 +- .../description.tsx | 4 +- .../categorization_view/field_examples.tsx | 4 +- .../detector_title/detector_title.tsx | 4 +- .../components/geo_field/description.tsx | 4 +- .../components/influencers/description.tsx | 4 +- .../population_field/description.tsx | 4 +- .../components/rare_field/description.tsx | 4 +- .../components/sparse_data/description.tsx | 4 +- .../components/split_cards/split_cards.tsx | 4 +- .../components/split_field/description.tsx | 4 +- .../summary_count_field/description.tsx | 4 +- .../summary_step/components/common.tsx | 6 +- .../components/wizard_nav/wizard_nav.tsx | 4 +- .../new_job/pages/new_job/wizard_steps.tsx | 7 +- .../components/notifications_list.test.tsx | 4 +- .../application/routing/ml_page_wrapper.tsx | 4 +- .../ml/public/application/routing/router.tsx | 7 +- .../timeseriesexplorer.test.tsx | 3 +- .../series_controls/series_controls.tsx | 4 +- .../timeseriesexplorer_page.tsx | 4 +- .../contexts/global_state_context.tsx | 4 +- .../application/pages/page_template.tsx | 4 +- .../chart_preview/chart_preview_helper.tsx | 4 +- .../use_kibana_environment_context.tsx | 11 +-- .../apm/public/hooks/use_breakpoints.test.tsx | 4 +- .../criterion_preview_chart.tsx | 6 +- .../inventory/components/expression.tsx | 12 ++- .../components/expression_editor/editor.tsx | 4 +- .../components/expression_row.tsx | 4 +- .../infra/public/apps/common_providers.tsx | 33 ++++---- .../components/loading_overlay_wrapper.tsx | 5 +- .../recreate_job_callout.tsx | 14 ++-- .../setup_flyout/setup_flyout.tsx | 11 ++- .../log_entry_examples/log_entry_examples.tsx | 5 +- .../infra/public/hooks/use_kibana.tsx | 14 +++- .../hooks/use_kibana_index_patterns.mock.tsx | 12 +-- .../log_entry_categories/page_providers.tsx | 4 +- .../logs/log_entry_rate/page_providers.tsx | 4 +- .../public/pages/logs/page_providers.tsx | 4 +- .../pages/logs/shared/page_log_view_error.tsx | 7 +- .../pages/logs/stream/page_providers.tsx | 30 ++++--- .../metric_detail/hooks/metrics_time.test.tsx | 4 +- .../pages/metrics/metric_detail/types.ts | 3 +- .../hooks/use_metrics_explorer_data.test.tsx | 4 +- .../test_utils/use_global_storybook_theme.tsx | 11 +-- .../utils/header_action_menu_provider.tsx | 4 +- .../public/utils/triggers_actions_context.tsx | 4 +- .../log_stream/log_stream_error_boundary.tsx | 11 +-- .../log_entry_actions_menu.test.tsx | 4 +- .../log_text_stream/column_headers.tsx | 12 +-- .../log_text_stream/log_text_separator.tsx | 4 +- .../test_utils/use_global_storybook_theme.tsx | 11 +-- .../criterion_preview_chart.tsx | 4 +- .../components/expression_row.tsx | 1 + .../public/hooks/use_conversation.test.tsx | 4 +- .../certificates/monitor_page_link.tsx | 7 +- .../react_router_helpers/link_for_eui.tsx | 1 + .../wrappers/service_allowed_wrapper.tsx | 4 +- .../monitor_add_edit/form/index.tsx | 16 ++-- .../monitor_pending_wrapper.tsx | 4 +- .../grid_by_group/grid_items_by_group.tsx | 7 +- .../private_locations/manage_empty_state.tsx | 16 ++-- .../view_location_monitors.tsx | 7 +- .../waterfall/context/waterfall_context.tsx | 11 ++- .../contexts/synthetics_data_view_context.tsx | 10 ++- .../contexts/synthetics_refresh_context.tsx | 13 +++- .../contexts/synthetics_settings_context.tsx | 4 +- .../synthetics_startup_plugins_context.tsx | 11 +-- .../contexts/synthetics_theme_context.tsx | 4 +- .../utils/testing/helper_with_redux.tsx | 14 ++-- .../charts/chart_wrapper/chart_wrapper.tsx | 4 +- .../components/common/monitor_page_link.tsx | 4 +- .../components/common/monitor_tags.test.tsx | 6 +- .../react_router_helpers/link_for_eui.tsx | 8 +- .../components/common/step_detail_link.tsx | 8 +- .../components/monitor/ml/ml_job_link.tsx | 9 ++- .../waterfall/context/waterfall_chart.tsx | 4 +- .../synthetics/code_block_accordion.tsx | 4 +- .../contexts/uptime_data_view_context.tsx | 10 ++- .../contexts/uptime_refresh_context.tsx | 4 +- .../contexts/uptime_settings_context.tsx | 7 +- .../uptime_startup_plugins_context.tsx | 11 +-- .../contexts/uptime_theme_context.tsx | 7 +- .../hooks/use_overview_filter_check.test.tsx | 4 +- .../lib/helper/helper_with_redux.tsx | 14 ++-- .../osquery_results/test_utils.tsx | 3 +- .../public/lib/default_status_context.tsx | 9 +-- .../public/lib/ilm_policy_status_context.tsx | 4 +- .../public/management/mount_section.tsx | 10 ++- .../public/components/title_panel.tsx | 4 +- .../sources_panel_for_sidebar.test.tsx | 4 +- .../sources_panel_for_start_chat.test.tsx | 4 +- .../public/components/start_chat_panel.tsx | 5 +- .../public/providers/playground_provider.tsx | 5 +- .../account_management_app.tsx | 5 +- .../user_profile/user_profile.test.tsx | 5 +- .../authentication_state_page.tsx | 4 +- .../security/public/components/breadcrumb.tsx | 4 +- .../security/public/components/doc_link.tsx | 4 +- .../security/public/components/form_label.tsx | 4 +- .../api_keys_grid/api_keys_empty_prompt.tsx | 4 +- .../api_keys_grid/api_keys_grid_page.tsx | 7 +- .../api_keys/api_keys_management_app.tsx | 4 +- .../management/users/users_management_app.tsx | 5 +- .../nav_control/nav_control_service.tsx | 4 +- .../security/public/ui_api/components.tsx | 2 +- .../security/public/ui_api/lazy_wrapper.tsx | 2 +- .../public/assistant/provider.tsx | 3 +- .../assistant/send_to_timeline/index.tsx | 2 +- .../public/common/__mocks__/query_wrapper.tsx | 3 +- .../components/current_license/index.tsx | 4 +- .../components/empty_prompt/empty_prompt.tsx | 2 +- .../components/endpoint/route_capture.tsx | 3 +- .../cti_details/threat_summary_view.tsx | 3 +- .../event_details/overview/overview_card.tsx | 5 +- .../table/investigate_in_timeline_button.tsx | 6 +- .../event_details_width_context.tsx | 3 +- .../components/health_truncate_text/index.tsx | 3 +- .../onboarding/__mocks__/product_switch.tsx | 5 +- .../onboarding/__mocks__/toggle_panel.tsx | 5 +- .../onboarding/context/step_context.tsx | 6 +- .../common/components/links/helpers.tsx | 6 +- .../permissions/ml_capabilities_provider.tsx | 3 +- .../security_route_page_wrapper/index.tsx | 2 +- .../common/hooks/use_upselling.test.tsx | 3 +- .../common/mock/storybook_providers.tsx | 3 +- .../dashboards/context/dashboard_context.tsx | 3 +- .../components/rule_preview/preview_logs.tsx | 3 +- .../rule_details/json_diff/diff_view.tsx | 5 +- .../rule_details/json_diff/json_diff.test.tsx | 5 +- .../rule_details/rule_details_flyout.tsx | 3 +- .../bulk_action_rule_errors_list.test.tsx | 4 +- .../use_execution_events.test.tsx | 3 +- .../use_execution_results.test.tsx | 3 +- .../use_host_isolation_action.test.tsx | 3 +- .../use_installed_integrations.test.tsx | 3 +- .../rule_status_failed_callout.test.tsx | 3 +- .../render_cell_value.tsx | 2 +- .../components/embeddables/embeddable.tsx | 3 +- .../correlations_details_alerts_table.tsx | 4 +- .../components/related_alerts_by_ancestry.tsx | 2 +- .../related_alerts_by_same_source_event.tsx | 2 +- .../components/related_alerts_by_session.tsx | 2 +- .../left/components/related_cases.tsx | 2 +- .../left/components/suppressed_alerts.tsx | 2 +- .../document_details/left/components/tour.tsx | 3 +- .../flyout/document_details/left/content.tsx | 4 +- .../flyout/document_details/left/header.tsx | 4 +- .../left/tabs/insights_tab.tsx | 2 +- .../left/tabs/investigation_tab.tsx | 2 +- .../left/tabs/response_tab.tsx | 2 +- .../left/tabs/visualize_tab.tsx | 3 +- .../preview/components/rule_preview.tsx | 2 +- .../components/rule_preview_footer.tsx | 2 +- .../right/components/about_section.tsx | 3 +- .../right/components/alert_header_title.tsx | 3 +- .../right/components/event_header_title.tsx | 3 +- .../right/components/insights_section.tsx | 3 +- .../components/investigation_section.tsx | 3 +- .../right/components/response_section.tsx | 3 +- .../right/components/risk_score.tsx | 3 +- .../right/components/session_preview.tsx | 4 +- .../right/components/severity.tsx | 3 +- .../right/components/tour.tsx | 3 +- .../components/visualizations_section.tsx | 3 +- .../flyout/document_details/right/content.tsx | 4 +- .../right/hooks/use_process_data.test.tsx | 4 +- .../document_details/right/tabs/json_tab.tsx | 3 +- .../right/tabs/overview_tab.tsx | 3 +- .../document_details/right/tabs/table_tab.tsx | 3 +- .../shared/components/expandable_panel.tsx | 3 +- .../components/administration_list_page.tsx | 6 +- .../exception_items_summary.test.tsx | 3 +- .../components/exception_items_summary.tsx | 52 +++++++------ ...oint_agent_tamper_protection_extension.tsx | 3 +- .../view/ingest_manager_integration/mocks.tsx | 3 +- .../policy_settings_form.tsx | 2 +- .../public/overview/pages/landing.test.tsx | 3 +- .../timeline/body/events/stateful_event.tsx | 2 +- .../data_providers/provider_badge.tsx | 2 +- .../data_providers/provider_item_actions.tsx | 11 +-- .../tabs/session/use_session_view.test.tsx | 3 +- .../unified_components/index.test.tsx | 4 +- .../public/common/services.tsx | 9 ++- .../common/services/__mocks__/index.tsx | 3 +- .../public/common/services/services.tsx | 9 ++- .../index_management/overview_panel.tsx | 4 +- .../application/components/overview.tsx | 4 +- .../public/test/test_utils.tsx | 4 +- .../spaces/public/spaces_context/context.tsx | 4 +- .../spaces/public/spaces_context/types.ts | 5 +- .../spaces/public/spaces_context/wrapper.tsx | 3 +- .../spaces/public/ui_api/components.tsx | 5 +- .../spaces/public/ui_api/lazy_wrapper.tsx | 2 +- .../components/source_fields_select.test.tsx | 4 +- .../expression/esql_query_expression.test.tsx | 4 +- .../test_query_row_table.test.tsx | 4 +- .../public/components/layout.tsx | 4 +- .../public/containers/enterprise_guard.tsx | 4 +- .../containers/field_types_provider.tsx | 4 +- .../public/containers/filters_global.tsx | 4 +- .../public/containers/inspector.tsx | 4 +- .../public/containers/integrations_guard.tsx | 4 +- .../security_solution_page_wrapper.tsx | 4 +- .../public/mocks/test_providers.tsx | 4 +- .../containers/block_list_provider.tsx | 11 ++- .../modules/indicators/containers/filters.tsx | 4 +- .../modules/indicators/pages/indicators.tsx | 4 +- .../app/components/capabilities_wrapper.tsx | 10 ++- .../public/app/hooks/use_index_data.test.tsx | 4 +- .../edit_transform_flyout_state.test.tsx | 4 +- .../transform_list/use_actions.test.tsx | 4 +- .../transform_list/use_columns.test.tsx | 4 +- .../public/app/serverless_context.tsx | 18 +++-- .../.storybook/decorator.tsx | 6 +- .../application/components/health_check.tsx | 4 +- .../toast_with_circuit_breaker_content.tsx | 4 +- .../application/context/connector_context.tsx | 11 +-- .../application/sections/test_utils.tsx | 6 +- .../components/loading_issues_error.tsx | 4 +- 493 files changed, 1531 insertions(+), 1174 deletions(-) diff --git a/examples/bfetch_explorer/public/components/page/index.tsx b/examples/bfetch_explorer/public/components/page/index.tsx index 6e282f528362b..07b7bf7a83209 100644 --- a/examples/bfetch_explorer/public/components/page/index.tsx +++ b/examples/bfetch_explorer/public/components/page/index.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiPageTemplate, EuiPageSection, EuiPageHeader } from '@elastic/eui'; export interface PageProps { @@ -14,7 +14,11 @@ export interface PageProps { sidebar?: React.ReactNode; } -export const Page: React.FC = ({ title = 'Untitled', sidebar, children }) => { +export const Page: FC> = ({ + title = 'Untitled', + sidebar, + children, +}) => { return ( {sidebar} diff --git a/examples/bfetch_explorer/public/containers/app/pages/page_count_until/index.tsx b/examples/bfetch_explorer/public/containers/app/pages/page_count_until/index.tsx index b0ed74a570bb4..14112dc4ffcc9 100644 --- a/examples/bfetch_explorer/public/containers/app/pages/page_count_until/index.tsx +++ b/examples/bfetch_explorer/public/containers/app/pages/page_count_until/index.tsx @@ -13,10 +13,7 @@ import { Page } from '../../../../components/page'; import { useDeps } from '../../../../hooks/use_deps'; import { Sidebar } from '../../sidebar'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface Props {} - -export const PageCountUntil: React.FC = () => { +export const PageCountUntil = () => { const { plugins } = useDeps(); return ( diff --git a/examples/bfetch_explorer/public/containers/app/pages/page_double_integers/index.tsx b/examples/bfetch_explorer/public/containers/app/pages/page_double_integers/index.tsx index 0af8218708cbb..5a5ba21c638fc 100644 --- a/examples/bfetch_explorer/public/containers/app/pages/page_double_integers/index.tsx +++ b/examples/bfetch_explorer/public/containers/app/pages/page_double_integers/index.tsx @@ -13,10 +13,7 @@ import { Page } from '../../../../components/page'; import { useDeps } from '../../../../hooks/use_deps'; import { Sidebar } from '../../sidebar'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface Props {} - -export const PageDoubleIntegers: React.FC = () => { +export const PageDoubleIntegers = () => { const { explorer } = useDeps(); return ( diff --git a/examples/response_stream/public/components/page.tsx b/examples/response_stream/public/components/page.tsx index 0b902558ee307..e3138fafa71ab 100644 --- a/examples/response_stream/public/components/page.tsx +++ b/examples/response_stream/public/components/page.tsx @@ -6,15 +6,14 @@ * Side Public License, v 1. */ -import * as React from 'react'; - +import React, { FC, PropsWithChildren } from 'react'; import { EuiPageTemplate, EuiTitle } from '@elastic/eui'; export interface PageProps { title?: React.ReactNode; } -export const Page: React.FC = ({ title = 'Untitled', children }) => { +export const Page: FC> = ({ title = 'Untitled', children }) => { return ( <> diff --git a/examples/search_examples/public/common/example_page.tsx b/examples/search_examples/public/common/example_page.tsx index 7be20aeef1d8d..ca52ebe1ae761 100644 --- a/examples/search_examples/public/common/example_page.tsx +++ b/examples/search_examples/public/common/example_page.tsx @@ -49,11 +49,11 @@ interface Props { basePath: IBasePath; } -export const SearchExamplePage: React.FC = ({ +export const SearchExamplePage: React.FC> = ({ children, exampleLinks, basePath, -}: PropsWithChildren) => { +}) => { return ( diff --git a/examples/state_containers_examples/public/common/example_page.tsx b/examples/state_containers_examples/public/common/example_page.tsx index b60fb87248d9f..1a18dfe79f68a 100644 --- a/examples/state_containers_examples/public/common/example_page.tsx +++ b/examples/state_containers_examples/public/common/example_page.tsx @@ -46,11 +46,11 @@ interface Props { exampleLinks: ExampleLink[]; } -export const StateContainersExamplesPage: React.FC = ({ +export const StateContainersExamplesPage: React.FC> = ({ navigateToApp, children, exampleLinks, -}: PropsWithChildren) => { +}) => { return ( diff --git a/examples/user_profile_examples/public/panel_with_code_block.tsx b/examples/user_profile_examples/public/panel_with_code_block.tsx index 17854fb3ad36d..366fca931e2bf 100644 --- a/examples/user_profile_examples/public/panel_with_code_block.tsx +++ b/examples/user_profile_examples/public/panel_with_code_block.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiTitle, EuiSpacer, EuiSplitPanel, EuiCodeBlock } from '@elastic/eui'; export interface PanelWithCodeBlockProps { @@ -13,7 +13,7 @@ export interface PanelWithCodeBlockProps { code: string; } -export const PanelWithCodeBlock: React.FunctionComponent = ({ +export const PanelWithCodeBlock: FC> = ({ title, code, children, diff --git a/packages/cloud/deployment_details/services.tsx b/packages/cloud/deployment_details/services.tsx index f25575cf8b01d..2b8ac4d1e65a4 100644 --- a/packages/cloud/deployment_details/services.tsx +++ b/packages/cloud/deployment_details/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; export interface DeploymentDetailsContextValue { cloudId?: string; @@ -22,7 +22,7 @@ const DeploymentDetailsContext = React.createContext = ({ +export const DeploymentDetailsProvider: FC> = ({ children, ...services }) => { @@ -75,10 +75,9 @@ export interface DeploymentDetailsKibanaDependencies { /** * Kibana-specific Provider that maps to known dependency types. */ -export const DeploymentDetailsKibanaProvider: FC = ({ - children, - ...services -}) => { +export const DeploymentDetailsKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => { const { core: { application: { navigateToUrl }, diff --git a/packages/content-management/content_editor/src/services.tsx b/packages/content-management/content_editor/src/services.tsx index 6666d3f3b0967..16d05d0a7978f 100644 --- a/packages/content-management/content_editor/src/services.tsx +++ b/packages/content-management/content_editor/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useContext, useCallback, useMemo } from 'react'; +import React, { useContext, useCallback, useMemo, PropsWithChildren } from 'react'; import type { FC, ReactNode } from 'react'; import type { Observable } from 'rxjs'; import type { EuiComboBoxProps } from '@elastic/eui'; @@ -45,7 +45,10 @@ const ContentEditorContext = React.createContext(null); /** * Abstract external service Provider. */ -export const ContentEditorProvider: FC = ({ children, ...services }) => { +export const ContentEditorProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; @@ -109,10 +112,9 @@ export interface ContentEditorKibanaDependencies { /** * Kibana-specific Provider that maps to known dependency types. */ -export const ContentEditorKibanaProvider: FC = ({ - children, - ...services -}) => { +export const ContentEditorKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => { const { core, toMountPoint, savedObjectsTagging } = services; const { openFlyout: coreOpenFlyout } = core.overlays; const { theme$ } = core.theme; diff --git a/packages/content-management/table_list_view_table/src/services.tsx b/packages/content-management/table_list_view_table/src/services.tsx index 3ed036612d2f9..612985ed6d331 100644 --- a/packages/content-management/table_list_view_table/src/services.tsx +++ b/packages/content-management/table_list_view_table/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext, useMemo, useCallback } from 'react'; +import React, { FC, PropsWithChildren, useContext, useMemo, useCallback } from 'react'; import type { Observable } from 'rxjs'; import type { FormattedRelative } from '@kbn/i18n-react'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; @@ -65,7 +65,10 @@ const TableListViewContext = React.createContext(null); /** * Abstract external service Provider. */ -export const TableListViewProvider: FC = ({ children, ...services }) => { +export const TableListViewProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; @@ -159,10 +162,9 @@ export interface TableListViewKibanaDependencies { /** * Kibana-specific Provider that maps to known dependency types. */ -export const TableListViewKibanaProvider: FC = ({ - children, - ...services -}) => { +export const TableListViewKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => { const { core, toMountPoint, savedObjectsTagging, FormattedRelative } = services; const searchQueryParser = useMemo(() => { diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/navigation.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/navigation.tsx index 83b7831831f29..954e7ec6dfb54 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/navigation.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/navigation.tsx @@ -6,15 +6,15 @@ * Side Public License, v 1. */ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, FC, PropsWithChildren } from 'react'; import { EuiCollapsibleNavBeta } from '@elastic/eui'; import useLocalStorage from 'react-use/lib/useLocalStorage'; const LOCAL_STORAGE_IS_COLLAPSED_KEY = 'PROJECT_NAVIGATION_COLLAPSED' as const; -export const ProjectNavigation: React.FC<{ - toggleSideNav: (isVisible: boolean) => void; -}> = ({ children, toggleSideNav }) => { +export const ProjectNavigation: FC< + PropsWithChildren<{ toggleSideNav: (isVisible: boolean) => void }> +> = ({ children, toggleSideNav }) => { const isMounted = useRef(false); const [isCollapsed, setIsCollapsed] = useLocalStorage(LOCAL_STORAGE_IS_COLLAPSED_KEY, false); const onCollapseToggle = (nextIsCollapsed: boolean) => { diff --git a/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx b/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx index 44fa1645eae95..2d657a4afcfb9 100644 --- a/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx +++ b/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx @@ -6,14 +6,15 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; + // eslint-disable-next-line @kbn/eslint/module_migration import { IntlProvider } from 'react-intl'; import { i18n } from '@kbn/i18n'; const emptyMessages = {}; -export const I18nProviderMock: React.FC = ({ children }) => { +export const I18nProviderMock: FC = ({ children }) => { return ( ; -}> = ({ chromeVisible$, children }) => { +export const AppWrapper: FC< + PropsWithChildren<{ + chromeVisible$: Observable; + }> +> = ({ chromeVisible$, children }) => { const visible = useObservable(chromeVisible$); return (
= ({ +export const CoreThemeProvider: FC> = ({ theme$, globalStyles, children, diff --git a/packages/home/sample_data_card/src/services.tsx b/packages/home/sample_data_card/src/services.tsx index 919e248875725..e1ee1fdbfb901 100644 --- a/packages/home/sample_data_card/src/services.tsx +++ b/packages/home/sample_data_card/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, MouseEventHandler, useContext } from 'react'; +import React, { FC, PropsWithChildren, MouseEventHandler, useContext } from 'react'; import { EuiGlobalToastListToast as EuiToast } from '@elastic/eui'; import { SAMPLE_DATA_API } from './constants'; @@ -41,7 +41,10 @@ const Context = React.createContext(null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const SampleDataCardProvider: FC = ({ children, ...services }) => { +export const SampleDataCardProvider: FC> = ({ + children, + ...services +}) => { const { addBasePath, getAppNavigationHandler, @@ -99,7 +102,7 @@ export interface KibanaDependencies { /** * Kibana-specific Provider that maps dependencies to services. */ -export const SampleDataCardKibanaProvider: FC = ({ +export const SampleDataCardKibanaProvider: FC> = ({ children, ...dependencies }) => { diff --git a/packages/home/sample_data_tab/src/services.tsx b/packages/home/sample_data_tab/src/services.tsx index b78c0f3507a0d..775834691b54e 100644 --- a/packages/home/sample_data_tab/src/services.tsx +++ b/packages/home/sample_data_tab/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import type { EuiGlobalToastListToast as EuiToast } from '@elastic/eui'; import type { SampleDataSet } from '@kbn/home-sample-data-types'; import { @@ -46,7 +46,10 @@ const Context = React.createContext(null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const SampleDataTabProvider: FC = ({ children, ...services }) => { +export const SampleDataTabProvider: FC> = ({ + children, + ...services +}) => { const { fetchSampleDataSets, notifyError, logClick } = services; return ( @@ -86,10 +89,9 @@ export type SampleDataTabKibanaDependencies = KibanaDependencies & SampleDataCar /** * Kibana-specific Provider that maps dependencies to services. */ -export const SampleDataTabKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const SampleDataTabKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { const { coreStart, trackUiMetric } = dependencies; const { http, notifications } = coreStart; diff --git a/packages/kbn-alerts-ui-shared/src/maintenance_window_callout/index.test.tsx b/packages/kbn-alerts-ui-shared/src/maintenance_window_callout/index.test.tsx index bb1866c82e90a..69ffd01d907c5 100644 --- a/packages/kbn-alerts-ui-shared/src/maintenance_window_callout/index.test.tsx +++ b/packages/kbn-alerts-ui-shared/src/maintenance_window_callout/index.test.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { render, waitFor, cleanup, screen } from '@testing-library/react'; @@ -24,7 +24,7 @@ jest.mock('./api', () => ({ fetchActiveMaintenanceWindows: jest.fn(() => Promise.resolve([])), })); -const TestProviders: React.FC<{}> = ({ children }) => { +const TestProviders: FC = ({ children }) => { const queryClient = new QueryClient(); return ( @@ -231,7 +231,7 @@ describe('MaintenanceWindowCallout', () => { warn: console.warn, }, }); - const wrapper: React.FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); return wrapper; diff --git a/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx b/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx index 5c9084d0e81dd..2184fc0fa7967 100644 --- a/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx +++ b/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx @@ -7,13 +7,13 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { makeAction, makeActionContext } from '../mocks/helpers'; import { CellActionsProvider, useCellActionsContext } from './cell_actions_context'; const action = makeAction('action-1', 'icon', 1); const mockGetTriggerCompatibleActions = jest.fn(async () => [action]); -const ContextWrapper: React.FC = ({ children }) => ( +const ContextWrapper: FC = ({ children }) => ( {children} diff --git a/packages/kbn-cell-actions/src/types.ts b/packages/kbn-cell-actions/src/types.ts index bd7cb69c38aac..301997618b6f3 100644 --- a/packages/kbn-cell-actions/src/types.ts +++ b/packages/kbn-cell-actions/src/types.ts @@ -5,6 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + +import { PropsWithChildren } from 'react'; import type { Action, ActionExecutionContext, @@ -14,13 +16,13 @@ import type { FieldSpec } from '@kbn/data-views-plugin/common'; import { Serializable } from '@kbn/utility-types'; import type { CellActionsMode } from './constants'; -export interface CellActionsProviderProps { +export type CellActionsProviderProps = PropsWithChildren<{ /** * Please assign `uiActions.getTriggerCompatibleActions` function. * This function should return a list of actions for a triggerId that are compatible with the provided context. */ getTriggerCompatibleActions: UiActionsService['getTriggerCompatibleActions']; -} +}>; type Metadata = Record; @@ -46,7 +48,7 @@ export interface CellActionsData { value: CellActionFieldValue; } -export interface CellActionsProps { +export type CellActionsProps = PropsWithChildren<{ data: CellActionsData | CellActionsData[]; /** @@ -82,7 +84,7 @@ export interface CellActionsProps { metadata?: Metadata; className?: string; -} +}>; export interface CellActionExecutionContext extends ActionExecutionContext { data: CellActionsData[]; diff --git a/packages/kbn-coloring/src/shared_components/coloring/__stories__/customizable_palette.stories.tsx b/packages/kbn-coloring/src/shared_components/coloring/__stories__/customizable_palette.stories.tsx index 5ab2de63f1dca..83accfecd4490 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/__stories__/customizable_palette.stories.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/__stories__/customizable_palette.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiForm } from '@elastic/eui'; import { ComponentStory } from '@storybook/react'; import { CustomizablePalette, CustomizablePaletteProps } from '../palette_configuration'; @@ -18,7 +18,7 @@ export default { decorators: [(story: Function) => {story()}], }; -const Template: ComponentStory> = (args) => ( +const Template: ComponentStory>> = (args) => ( ); diff --git a/packages/kbn-dom-drag-drop/src/drop_overlay_wrapper.tsx b/packages/kbn-dom-drag-drop/src/drop_overlay_wrapper.tsx index 65470de4d68d8..4c1d61608ba45 100644 --- a/packages/kbn-dom-drag-drop/src/drop_overlay_wrapper.tsx +++ b/packages/kbn-dom-drag-drop/src/drop_overlay_wrapper.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import classnames from 'classnames'; /** @@ -27,7 +27,7 @@ export interface DropOverlayWrapperProps { * @param otherProps * @constructor */ -export const DropOverlayWrapper: React.FC = ({ +export const DropOverlayWrapper: React.FC> = ({ isVisible, children, overlayProps, diff --git a/packages/kbn-i18n-react/src/provider.tsx b/packages/kbn-i18n-react/src/provider.tsx index 5e60188d3bdd4..cc3a5c475ce6f 100644 --- a/packages/kbn-i18n-react/src/provider.tsx +++ b/packages/kbn-i18n-react/src/provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; // eslint-disable-next-line @kbn/eslint/module_migration import { IntlProvider } from 'react-intl'; @@ -20,7 +20,7 @@ import { PseudoLocaleWrapper } from './pseudo_locale_wrapper'; * IntlProvider should wrap react app's root component (inside each react render method). */ -export const I18nProvider: React.FC = ({ children }) => ( +export const I18nProvider: FC = ({ children }) => ( (null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const SettingsApplicationProvider: FC = ({ +export const SettingsApplicationProvider: FC> = ({ children, ...services }) => { @@ -114,10 +114,9 @@ export const SettingsApplicationProvider: FC = ({ /** * Kibana-specific Provider that maps dependencies to services. */ -export const SettingsApplicationKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const SettingsApplicationKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { const { docLinks, notifications, diff --git a/packages/kbn-management/settings/components/field_input/services.tsx b/packages/kbn-management/settings/components/field_input/services.tsx index d19278268b2a6..e1ae741f14837 100644 --- a/packages/kbn-management/settings/components/field_input/services.tsx +++ b/packages/kbn-management/settings/components/field_input/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import type { FieldInputServices, FieldInputKibanaDependencies } from './types'; const FieldInputContext = React.createContext(null); @@ -14,7 +14,10 @@ const FieldInputContext = React.createContext(null); /** * React Provider that provides services to a {@link FieldInput} component and its dependents. */ -export const FieldInputProvider: FC = ({ children, ...services }) => { +export const FieldInputProvider: FC> = ({ + children, + ...services +}) => { // Typescript types are widened to accept more than what is needed. Take only what is necessary // so the context remains clean. const { showDanger, validateChange } = services; @@ -29,7 +32,7 @@ export const FieldInputProvider: FC = ({ children, ...servic /** * Kibana-specific Provider that maps Kibana plugins and services to a {@link FieldInputProvider}. */ -export const FieldInputKibanaProvider: FC = ({ +export const FieldInputKibanaProvider: FC> = ({ children, notifications: { toasts }, settings: { client }, diff --git a/packages/kbn-management/settings/components/field_row/services.tsx b/packages/kbn-management/settings/components/field_row/services.tsx index 6350b7f7cd103..bcf94c12aa04a 100644 --- a/packages/kbn-management/settings/components/field_row/services.tsx +++ b/packages/kbn-management/settings/components/field_row/services.tsx @@ -10,7 +10,7 @@ import { FieldInputKibanaProvider, FieldInputProvider, } from '@kbn/management-settings-components-field-input/services'; -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import type { FieldRowServices, FieldRowKibanaDependencies, Services } from './types'; @@ -41,7 +41,7 @@ export const FieldRowProvider = ({ children, ...services }: FieldRowProviderProp /** * Kibana-specific Provider that maps Kibana plugins and services to a {@link FieldRowProvider}. */ -export const FieldRowKibanaProvider: FC = ({ +export const FieldRowKibanaProvider: FC> = ({ children, docLinks, notifications, diff --git a/packages/kbn-management/settings/components/form/services.tsx b/packages/kbn-management/settings/components/form/services.tsx index ae2681fe88fcf..f59adc304db8d 100644 --- a/packages/kbn-management/settings/components/form/services.tsx +++ b/packages/kbn-management/settings/components/form/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import { FieldCategoryKibanaProvider, @@ -41,7 +41,10 @@ export const FormProvider = ({ children, ...services }: FormProviderProps) => { /** * Kibana-specific Provider that maps Kibana plugins and services to a {@link FormProvider}. */ -export const FormKibanaProvider: FC = ({ children, ...deps }) => { +export const FormKibanaProvider: FC> = ({ + children, + ...deps +}) => { const { settings, notifications, docLinks, theme, i18n } = deps; const services: Services = { diff --git a/packages/kbn-reporting/public/context.tsx b/packages/kbn-reporting/public/context.tsx index 667607fc0396d..f8cfcaff68171 100644 --- a/packages/kbn-reporting/public/context.tsx +++ b/packages/kbn-reporting/public/context.tsx @@ -7,7 +7,7 @@ */ import type { HttpSetup } from '@kbn/core/public'; -import React, { createContext, useContext, type FunctionComponent } from 'react'; +import React, { createContext, useContext, type FC, type PropsWithChildren } from 'react'; import { ReportingAPIClient } from './reporting_api_client'; interface ContextValue { @@ -17,10 +17,12 @@ interface ContextValue { const InternalApiClientContext = createContext(undefined); -export const InternalApiClientProvider: FunctionComponent<{ - apiClient: ReportingAPIClient; - http: HttpSetup; -}> = ({ apiClient, http, children }) => { +export const InternalApiClientProvider: FC< + PropsWithChildren<{ + apiClient: ReportingAPIClient; + http: HttpSetup; + }> +> = ({ apiClient, http, children }) => { return ( {children} diff --git a/packages/kbn-search-api-panels/components/overview_panel.tsx b/packages/kbn-search-api-panels/components/overview_panel.tsx index 201c67d5852bc..3890f96ff60d3 100644 --- a/packages/kbn-search-api-panels/components/overview_panel.tsx +++ b/packages/kbn-search-api-panels/components/overview_panel.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment } from 'react'; +import React, { Fragment, FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, @@ -29,7 +29,7 @@ interface OverviewPanelProps { overviewPanelProps?: Partial; } -export const OverviewPanel: React.FC = ({ +export const OverviewPanel: FC> = ({ children, description, leftPanelContent, diff --git a/packages/kbn-search-api-panels/components/select_client.tsx b/packages/kbn-search-api-panels/components/select_client.tsx index 59377d384e9d2..1dcd5c0458daf 100644 --- a/packages/kbn-search-api-panels/components/select_client.tsx +++ b/packages/kbn-search-api-panels/components/select_client.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiCallOut, @@ -34,9 +34,10 @@ export interface SelectClientPanelProps { application?: ApplicationStart; consolePlugin?: ConsolePluginStart; sharePlugin: SharePluginStart; + children: React.ReactNode; } -export const SelectClientPanel: React.FC = ({ +export const SelectClientPanel: FC> = ({ docLinks, children, isPanelLeft = true, diff --git a/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx b/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx index 1377626f3cd58..49b98ed6a2ea3 100644 --- a/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx +++ b/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { createContext, useEffect, useRef, useState } from 'react'; +import React, { createContext, useEffect, useRef, useState, FC, PropsWithChildren } from 'react'; import { EuiButton, @@ -46,6 +46,7 @@ interface ConnectorConfigurationProps { saveConfig: (configuration: Record) => void; stackManagementLink?: string; subscriptionLink?: string; + children?: React.ReactNode; } interface ConfigEntry extends ConnectorConfigProperties { @@ -80,7 +81,9 @@ export const LicenseContext = createContext<{ stackManagementLink: undefined, }); -export const ConnectorConfigurationComponent: React.FC = ({ +export const ConnectorConfigurationComponent: FC< + PropsWithChildren +> = ({ children, connector, hasPlatinumLicense, diff --git a/packages/kbn-search-connectors/components/scheduling/connector_scheduling.tsx b/packages/kbn-search-connectors/components/scheduling/connector_scheduling.tsx index 68d3f354a14f8..339c353cbf589 100644 --- a/packages/kbn-search-connectors/components/scheduling/connector_scheduling.tsx +++ b/packages/kbn-search-connectors/components/scheduling/connector_scheduling.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState, FC, PropsWithChildren } from 'react'; import { EuiCallOut, EuiFlexGroup, @@ -31,7 +31,11 @@ interface SchedulePanelProps { description: string; title: string; } -export const SchedulePanel: React.FC = ({ title, description, children }) => { +export const SchedulePanel: FC> = ({ + title, + description, + children, +}) => { return ( <> diff --git a/packages/kbn-search-connectors/components/sync_jobs/flyout_panel.tsx b/packages/kbn-search-connectors/components/sync_jobs/flyout_panel.tsx index 699a889150e6b..07cbf64a47949 100644 --- a/packages/kbn-search-connectors/components/sync_jobs/flyout_panel.tsx +++ b/packages/kbn-search-connectors/components/sync_jobs/flyout_panel.tsx @@ -6,15 +6,14 @@ * Side Public License, v 1. */ -import React from 'react'; - +import React, { FC, PropsWithChildren } from 'react'; import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; interface FlyoutPanelProps { title: string; } -export const FlyoutPanel: React.FC = ({ children, title }) => { +export const FlyoutPanel: FC> = ({ children, title }) => { return ( diff --git a/packages/kbn-shared-ux-utility/src/dynamic/test_component.tsx b/packages/kbn-shared-ux-utility/src/dynamic/test_component.tsx index 058481ea5f8aa..e000468e062c0 100644 --- a/packages/kbn-shared-ux-utility/src/dynamic/test_component.tsx +++ b/packages/kbn-shared-ux-utility/src/dynamic/test_component.tsx @@ -6,20 +6,23 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; export interface TestComponentProps { customProp?: boolean; + children?: React.ReactNode; } -export const TestComponent: React.FunctionComponent = ({ children }) => { +export const TestComponent: FC> = ({ children }) => { return {children} Test component; }; -export const ForwardeRefTestComponent: React.FunctionComponent = - React.forwardRef(({ children }, ref) => { - return {children} Test component; - }); +export const ForwardeRefTestComponent: FC> = React.forwardRef< + HTMLSpanElement, + PropsWithChildren +>(({ children }, ref) => { + return {children} Test component; +}); // eslint-disable-next-line import/no-default-export export default TestComponent; diff --git a/packages/kbn-unified-data-table/src/components/compare_documents/comparison_controls.tsx b/packages/kbn-unified-data-table/src/components/compare_documents/comparison_controls.tsx index 6787c9e56dd05..48c4f11960e57 100644 --- a/packages/kbn-unified-data-table/src/components/compare_documents/comparison_controls.tsx +++ b/packages/kbn-unified-data-table/src/components/compare_documents/comparison_controls.tsx @@ -24,7 +24,7 @@ import { useEuiTheme, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { FC, ReactNode, useState } from 'react'; +import React, { FC, PropsWithChildren, ReactNode, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { DocumentDiffMode } from './types'; @@ -368,10 +368,12 @@ const enableShowDiffTooltip = i18n.translate('unifiedDataTable.enableShowDiff', }); const DiffModeEntry: FC< - Pick & { - entryDiffMode: DocumentDiffMode; - disabled?: boolean; - } + PropsWithChildren< + Pick & { + entryDiffMode: DocumentDiffMode; + disabled?: boolean; + } + > > = ({ children, entryDiffMode, diffMode, disabled, setDiffMode }) => { const { euiTheme } = useEuiTheme(); diff --git a/packages/kbn-unified-data-table/src/components/data_table_footer.tsx b/packages/kbn-unified-data-table/src/components/data_table_footer.tsx index 21819a023afed..dc84bbf6d452f 100644 --- a/packages/kbn-unified-data-table/src/components/data_table_footer.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table_footer.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, FC, PropsWithChildren } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiButtonEmpty, EuiToolTip, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -28,7 +28,9 @@ export interface UnifiedDataTableFooterProps { fieldFormats: FieldFormatsStart; } -export const UnifiedDataTableFooter: React.FC = (props) => { +export const UnifiedDataTableFooter: FC> = ( + props +) => { const { isLoadingMore, rowCount, diff --git a/packages/kbn-unified-field-list/src/components/field_list/field_list.tsx b/packages/kbn-unified-field-list/src/components/field_list/field_list.tsx index 29bc5f00cddf9..47888a6df5dc5 100644 --- a/packages/kbn-unified-field-list/src/components/field_list/field_list.tsx +++ b/packages/kbn-unified-field-list/src/components/field_list/field_list.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiProgress } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -39,7 +39,7 @@ export interface FieldListProps { * @public * @constructor */ -export const FieldList: React.FC = ({ +export const FieldList: FC> = ({ 'data-test-subj': dataTestSubject = 'fieldList', isProcessing, prepend, diff --git a/packages/kbn-user-profile-components/src/services.tsx b/packages/kbn-user-profile-components/src/services.tsx index 71ce5a0ff844f..f70b7e2e65c41 100644 --- a/packages/kbn-user-profile-components/src/services.tsx +++ b/packages/kbn-user-profile-components/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { NotificationsStart, ToastOptions } from '@kbn/core-notifications-browser'; @@ -30,7 +30,10 @@ const UserProfilesContext = React.createContext(null); /** * Abstract external service Provider. */ -export const UserProfilesProvider: FC = ({ children, ...services }) => { +export const UserProfilesProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; @@ -60,7 +63,7 @@ export interface UserProfilesKibanaDependencies { /** * Kibana-specific Provider that maps to known dependency types. */ -export const UserProfilesKibanaProvider: FC = ({ +export const UserProfilesKibanaProvider: FC> = ({ children, ...services }) => { diff --git a/packages/react/kibana_context/render/render_provider.tsx b/packages/react/kibana_context/render/render_provider.tsx index 205f9008e6470..bf66d5f662308 100644 --- a/packages/react/kibana_context/render/render_provider.tsx +++ b/packages/react/kibana_context/render/render_provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { KibanaRootContextProvider, @@ -21,10 +21,9 @@ export type KibanaRenderContextProviderProps = Omit = ({ - children, - ...props -}) => { +export const KibanaRenderContextProvider: FC< + PropsWithChildren +> = ({ children, ...props }) => { return ( diff --git a/packages/react/kibana_context/root/eui_provider.tsx b/packages/react/kibana_context/root/eui_provider.tsx index 79a017dc80c79..29745997b80bd 100644 --- a/packages/react/kibana_context/root/eui_provider.tsx +++ b/packages/react/kibana_context/root/eui_provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useMemo } from 'react'; +import React, { FC, PropsWithChildren, useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; import createCache from '@emotion/cache'; @@ -56,7 +56,7 @@ const cache = { default: emotionCache, global: globalCache, utility: utilitiesCa * Prepares and returns a configured `EuiProvider` for use in Kibana roots. In most cases, this utility context * should not be used. Instead, refer to `KibanaRootContextProvider` to set up the root of Kibana. */ -export const KibanaEuiProvider: FC = ({ +export const KibanaEuiProvider: FC> = ({ theme: { theme$ }, globalStyles: globalStylesProp, colorMode: colorModeProp, diff --git a/packages/react/kibana_context/root/root_provider.tsx b/packages/react/kibana_context/root/root_provider.tsx index ad95cf8e437e5..19cce446e5f11 100644 --- a/packages/react/kibana_context/root/root_provider.tsx +++ b/packages/react/kibana_context/root/root_provider.tsx @@ -8,7 +8,7 @@ import type { I18nStart } from '@kbn/core-i18n-browser'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { KibanaEuiProvider, type KibanaEuiProviderProps } from './eui_provider'; @@ -34,7 +34,7 @@ export interface KibanaRootContextProviderProps extends KibanaEuiProviderProps { * - Consider `KibanaThemeContextProvider` for altering the theme of a component or tree of components. * */ -export const KibanaRootContextProvider: FC = ({ +export const KibanaRootContextProvider: FC> = ({ children, i18n, ...props diff --git a/packages/react/kibana_mount/mount_point_portal.tsx b/packages/react/kibana_mount/mount_point_portal.tsx index dcfeddc428d09..5e950bcec19b6 100644 --- a/packages/react/kibana_mount/mount_point_portal.tsx +++ b/packages/react/kibana_mount/mount_point_portal.tsx @@ -7,19 +7,23 @@ */ import { i18n } from '@kbn/i18n'; -import React, { useRef, useEffect, useState, Component } from 'react'; +import React, { useRef, useEffect, useState, Component, FC, PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import { MountPoint } from '@kbn/core/public'; import { useIfMounted } from './utils'; export interface MountPointPortalProps { setMountPoint: (mountPoint: MountPoint | undefined) => void; + children: React.ReactNode; } /** * Utility component to portal a part of a react application into the provided `MountPoint`. */ -export const MountPointPortal: React.FC = ({ children, setMountPoint }) => { +export const MountPointPortal: FC> = ({ + children, + setMountPoint, +}) => { // state used to force re-renders when the element changes const [shouldRender, setShouldRender] = useState(false); const el = useRef(); diff --git a/packages/serverless/project_switcher/src/services.tsx b/packages/serverless/project_switcher/src/services.tsx index 413de92d4f1ad..f928f79073bf1 100644 --- a/packages/serverless/project_switcher/src/services.tsx +++ b/packages/serverless/project_switcher/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import ReactDOM from 'react-dom'; import { Loader } from './loader'; @@ -17,14 +17,17 @@ const Context = React.createContext(null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const ProjectSwitcherProvider: FC = ({ children, ...services }) => { +export const ProjectSwitcherProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; /** * Kibana-specific Provider that maps dependencies to services. */ -export const ProjectSwitcherKibanaProvider: FC = ({ +export const ProjectSwitcherKibanaProvider: FC> = ({ children, coreStart, projectChangeAPIUrl, diff --git a/packages/shared-ux/button/exit_full_screen/src/services.tsx b/packages/shared-ux/button/exit_full_screen/src/services.tsx index 5a4111e4627df..2f3cad45b7c95 100644 --- a/packages/shared-ux/button/exit_full_screen/src/services.tsx +++ b/packages/shared-ux/button/exit_full_screen/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, useContext, PropsWithChildren } from 'react'; import type { Services, @@ -19,7 +19,7 @@ const ExitFullScreenButtonContext = React.createContext(null); /** * Abstract external service Provider. */ -export const ExitFullScreenButtonProvider: FC = ({ +export const ExitFullScreenButtonProvider: FC> = ({ children, ...services }) => { @@ -33,10 +33,9 @@ export const ExitFullScreenButtonProvider: FC = ({ /** * Kibana-specific Provider that maps to known dependency types. */ -export const ExitFullScreenButtonKibanaProvider: FC = ({ - children, - ...services -}) => { +export const ExitFullScreenButtonKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => { return ( (null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const NoDataCardProvider: FC = ({ children, ...services }) => { +export const NoDataCardProvider: FC> = ({ + children, + ...services +}) => { const { addBasePath, canAccessFleet } = services; return ( @@ -36,7 +39,7 @@ export const NoDataCardProvider: FC = ({ children, ...servic /** * Kibana-specific Provider that maps dependencies to services. */ -export const NoDataCardKibanaProvider: FC = ({ +export const NoDataCardKibanaProvider: FC> = ({ children, ...dependencies }) => { diff --git a/packages/shared-ux/chrome/navigation/src/services.tsx b/packages/shared-ux/chrome/navigation/src/services.tsx index 178b2d279e55a..617e5695579f3 100644 --- a/packages/shared-ux/chrome/navigation/src/services.tsx +++ b/packages/shared-ux/chrome/navigation/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { NavigationKibanaDependencies, NavigationServices } from './types'; @@ -16,14 +16,17 @@ const Context = React.createContext(null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const NavigationProvider: FC = ({ children, ...services }) => { +export const NavigationProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; /** * Kibana-specific Provider that maps dependencies to services. */ -export const NavigationKibanaProvider: FC = ({ +export const NavigationKibanaProvider: FC> = ({ children, ...dependencies }) => { diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx index 7eee3515c49c3..aa9dbb7b6a6d0 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx @@ -6,7 +6,15 @@ * Side Public License, v 1. */ -import React, { type FC, useCallback, useContext, useMemo, useState, ReactNode } from 'react'; +import React, { + type FC, + type PropsWithChildren, + useCallback, + useContext, + useMemo, + useState, + ReactNode, +} from 'react'; import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; import { DefaultContent } from './default_content'; @@ -30,7 +38,11 @@ interface Props { activeNodes: ChromeProjectNavigationNode[][]; } -export const PanelProvider: FC = ({ children, contentProvider, activeNodes }) => { +export const PanelProvider: FC> = ({ + children, + contentProvider, + activeNodes, +}) => { const [isOpen, setIsOpen] = useState(false); const [selectedNode, setActiveNode] = useState(null); diff --git a/packages/shared-ux/error_boundary/mocks/src/storybook_template.tsx b/packages/shared-ux/error_boundary/mocks/src/storybook_template.tsx index e120cc5d3584f..ab22e88289e08 100644 --- a/packages/shared-ux/error_boundary/mocks/src/storybook_template.tsx +++ b/packages/shared-ux/error_boundary/mocks/src/storybook_template.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiCollapsibleNavBeta, @@ -16,7 +16,7 @@ import { EuiPageTemplate, } from '@elastic/eui'; -export const Template: FC = ({ children }) => { +export const Template: FC = ({ children }) => { return ( <> diff --git a/packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx b/packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx index fdb6df5d0dde2..03ea414b4cd03 100644 --- a/packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx +++ b/packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext, useMemo } from 'react'; +import React, { FC, PropsWithChildren, useContext, useMemo } from 'react'; import { KibanaErrorBoundaryProviderDeps, KibanaErrorBoundaryServices } from '../../types'; import { KibanaErrorService } from './error_service'; @@ -17,21 +17,20 @@ const Context = React.createContext(null); * A Context Provider for Jest and Storybooks * @internal */ -export const KibanaErrorBoundaryDepsProvider: FC = ({ - children, - onClickRefresh, - errorService, -}) => {children}; +export const KibanaErrorBoundaryDepsProvider: FC< + PropsWithChildren +> = ({ children, onClickRefresh, errorService }) => ( + {children} +); /** * Provider that uses dependencies to give context to the KibanaErrorBoundary component * This provider is aware if services were already created from a higher level of the component tree * @public */ -export const KibanaErrorBoundaryProvider: FC = ({ - children, - analytics, -}) => { +export const KibanaErrorBoundaryProvider: FC< + PropsWithChildren +> = ({ children, analytics }) => { const parentContext = useContext(Context); const value: KibanaErrorBoundaryServices = useMemo(() => { // FIXME: analytics dep is optional - know when not to overwrite diff --git a/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx b/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx index 0d67cfd54becd..bc3fa49741ac8 100644 --- a/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx +++ b/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx @@ -7,7 +7,7 @@ */ import { render } from '@testing-library/react'; -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { KibanaErrorBoundary } from '../..'; import { BadComponent, ChunkLoadErrorComponent, getServicesMock } from '../../mocks'; @@ -22,7 +22,7 @@ describe('', () => { services = getServicesMock(); }); - const Template: FC = ({ children }) => { + const Template: FC = ({ children }) => { return ( {children} diff --git a/packages/shared-ux/file/context/src/index.tsx b/packages/shared-ux/file/context/src/index.tsx index da0c70df6c01c..385c093da3d7b 100644 --- a/packages/shared-ux/file/context/src/index.tsx +++ b/packages/shared-ux/file/context/src/index.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { createContext, useContext, type FunctionComponent } from 'react'; +import React, { createContext, useContext, type FC, type PropsWithChildren } from 'react'; import type { BaseFilesClient as FilesClient } from '@kbn/shared-ux-file-types'; export interface FilesContextValue { @@ -31,8 +31,9 @@ interface ContextProps { * A files client that will be used process uploads. */ client: FilesClient; + children: React.ReactNode; } -export const FilesContext: FunctionComponent = ({ client, children }) => { +export const FilesContext: FC> = ({ client, children }) => { return ( = ({ +export const FilePickerContext: FC> = ({ kind, shouldAllowDelete, pageSize, diff --git a/packages/shared-ux/link/redirect_app/impl/src/services.tsx b/packages/shared-ux/link/redirect_app/impl/src/services.tsx index 8301bb43ad67c..eb2021b5d0662 100644 --- a/packages/shared-ux/link/redirect_app/impl/src/services.tsx +++ b/packages/shared-ux/link/redirect_app/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { @@ -19,7 +19,7 @@ const RedirectAppLinksContext = React.createContext = ({ +export const RedirectAppLinksProvider: FC> = ({ children, ...services }) => { @@ -34,10 +34,9 @@ export const RedirectAppLinksProvider: FC = ({ /** * Kibana-specific contextual services Provider. */ -export const RedirectAppLinksKibanaProvider: FC = ({ - children, - coreStart, -}) => { +export const RedirectAppLinksKibanaProvider: FC< + PropsWithChildren +> = ({ children, coreStart }) => { const { navigateToUrl, currentAppId$ } = coreStart.application; const currentAppId = useObservable(currentAppId$, undefined); diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/services.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/services.tsx index f79861f680a0d..a23b32b34cf0f 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/services.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import { KibanaNoDataPageKibanaProvider, KibanaNoDataPageProvider, @@ -23,7 +23,7 @@ const Context = React.createContext(null); /** * A Context Provider that provides services to the component and its dependencies. */ -export const AnalyticsNoDataPageProvider: FC = ({ +export const AnalyticsNoDataPageProvider: FC> = ({ children, ...services }) => { @@ -41,10 +41,9 @@ export const AnalyticsNoDataPageProvider: FC = ({ /** * Kibana-specific Provider that maps dependencies to services. */ -export const AnalyticsNoDataPageKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const AnalyticsNoDataPageKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { const value: Services = { kibanaGuideDocLink: dependencies.coreStart.docLinks.links.kibana.guide, customBranding: { diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx index 3ebab02d63790..0fc1d69018dc4 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import { NoDataViewsPromptProvider, NoDataViewsPromptKibanaProvider, @@ -25,7 +25,7 @@ const KibanaNoDataPageContext = React.createContext(null); /** * A Context Provider that provides services to the component. */ -export const KibanaNoDataPageProvider: FC = ({ +export const KibanaNoDataPageProvider: FC> = ({ children, ...services }) => { @@ -43,10 +43,9 @@ export const KibanaNoDataPageProvider: FC = ({ /** * Kibana-specific Provider that maps dependencies to services. */ -export const KibanaNoDataPageKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const KibanaNoDataPageKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { const { dataViews } = dependencies; const value: Services = { hasESData: dataViews.hasData.hasESData, diff --git a/packages/shared-ux/page/kibana_template/impl/src/services.tsx b/packages/shared-ux/page/kibana_template/impl/src/services.tsx index 328d3e8a6f9c8..25d4c4ac4c856 100644 --- a/packages/shared-ux/page/kibana_template/impl/src/services.tsx +++ b/packages/shared-ux/page/kibana_template/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { NoDataConfigPageProvider, @@ -21,7 +21,7 @@ import { /** * A Context Provider that provides services to the component and its dependencies. */ -export const KibanaPageTemplateProvider: FC = ({ +export const KibanaPageTemplateProvider: FC> = ({ children, ...services }) => { @@ -31,10 +31,9 @@ export const KibanaPageTemplateProvider: FC = ({ /** * Kibana-specific Provider that maps dependencies to services. */ -export const KibanaPageTemplateKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const KibanaPageTemplateKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { return ( {children} ); diff --git a/packages/shared-ux/page/no_data/impl/src/services.tsx b/packages/shared-ux/page/no_data/impl/src/services.tsx index 3d10cc5547c92..95ad07c79526a 100644 --- a/packages/shared-ux/page/no_data/impl/src/services.tsx +++ b/packages/shared-ux/page/no_data/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { NoDataCardKibanaProvider, NoDataCardProvider } from '@kbn/shared-ux-card-no-data'; @@ -18,14 +18,17 @@ import type { /** * A Context Provider that provides services to the component and its dependencies. */ -export const NoDataPageProvider: FC = ({ children, ...services }) => { +export const NoDataPageProvider: FC> = ({ + children, + ...services +}) => { return {children}; }; /** * Kibana-specific Provider that maps dependencies to services. */ -export const NoDataPageKibanaProvider: FC = ({ +export const NoDataPageKibanaProvider: FC> = ({ children, ...dependencies }) => { diff --git a/packages/shared-ux/page/no_data_config/impl/src/services.tsx b/packages/shared-ux/page/no_data_config/impl/src/services.tsx index a7d0d118c053d..998343abf28f1 100644 --- a/packages/shared-ux/page/no_data_config/impl/src/services.tsx +++ b/packages/shared-ux/page/no_data_config/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { NoDataPageProvider, NoDataPageKibanaProvider } from '@kbn/shared-ux-page-no-data'; import type { @@ -17,7 +17,7 @@ import type { /** * A Context Provider that provides services to the component and its dependencies. */ -export const NoDataConfigPageProvider: FC = ({ +export const NoDataConfigPageProvider: FC> = ({ children, ...services }) => { @@ -27,9 +27,8 @@ export const NoDataConfigPageProvider: FC = ({ /** * Kibana-specific Provider that maps dependencies to services. */ -export const NoDataConfigPageKibanaProvider: FC = ({ - children, - ...dependencies -}) => { +export const NoDataConfigPageKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...dependencies }) => { return {children}; }; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx index 6e282fc6b3a18..277e93dd6d800 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useContext } from 'react'; +import React, { FC, PropsWithChildren, useContext } from 'react'; import type { NoDataViewsPromptServices, @@ -19,7 +19,7 @@ const NoDataViewsPromptContext = React.createContext = ({ +export const NoDataViewsPromptProvider: FC> = ({ children, ...services }) => { @@ -46,10 +46,9 @@ export const NoDataViewsPromptProvider: FC = ({ /** * Kibana-specific Provider that maps to known dependency types. */ -export const NoDataViewsPromptKibanaProvider: FC = ({ - children, - ...services -}) => { +export const NoDataViewsPromptKibanaProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => { const { share, coreStart: { diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/mosaic_vis_renderer.stories.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/mosaic_vis_renderer.stories.tsx index f43d7d8840b87..9790260edff35 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/mosaic_vis_renderer.stories.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/mosaic_vis_renderer.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ComponentStory } from '@storybook/react'; import { Render } from '@kbn/presentation-util-plugin/public/__stories__'; import { getPartitionVisRenderer } from '../expression_renderers'; @@ -26,7 +26,7 @@ type Props = { syncColors: PartitionChartProps['syncColors']; } & PartitionChartProps['visConfig']; -const PartitionVis: ComponentStory> = ({ +const PartitionVis: ComponentStory>> = ({ visType, syncColors, children, diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/pie_vis_renderer.stories.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/pie_vis_renderer.stories.tsx index e896c3b382928..2b9457683df4e 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/pie_vis_renderer.stories.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/pie_vis_renderer.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ComponentStory } from '@storybook/react'; import { Render } from '@kbn/presentation-util-plugin/public/__stories__'; import { getPartitionVisRenderer } from '../expression_renderers'; @@ -26,7 +26,7 @@ type Props = { syncColors: PartitionChartProps['syncColors']; } & PartitionChartProps['visConfig']; -const PartitionVis: ComponentStory> = ({ +const PartitionVis: ComponentStory>> = ({ visType, syncColors, children, diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/treemap_vis_renderer.stories.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/treemap_vis_renderer.stories.tsx index 6b9248292c69b..efd5263b6af5c 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/treemap_vis_renderer.stories.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/treemap_vis_renderer.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ComponentStory } from '@storybook/react'; import { Render } from '@kbn/presentation-util-plugin/public/__stories__'; import { getPartitionVisRenderer } from '../expression_renderers'; @@ -26,7 +26,7 @@ type Props = { syncColors: PartitionChartProps['syncColors']; } & PartitionChartProps['visConfig']; -const PartitionVis: ComponentStory> = ({ +const PartitionVis: ComponentStory>> = ({ visType, syncColors, children, diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/waffle_vis_renderer.stories.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/waffle_vis_renderer.stories.tsx index d2c472018cf78..9cc278ea3c41d 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/waffle_vis_renderer.stories.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/__stories__/waffle_vis_renderer.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ComponentStory } from '@storybook/react'; import { Render } from '@kbn/presentation-util-plugin/public/__stories__'; import { getPartitionVisRenderer } from '../expression_renderers'; @@ -26,7 +26,7 @@ type Props = { syncColors: PartitionChartProps['syncColors']; } & PartitionChartProps['visConfig']; -const PartitionVis: ComponentStory> = ({ +const PartitionVis: ComponentStory>> = ({ visType, syncColors, children, diff --git a/src/plugins/content_management/public/content_client/content_client_context.tsx b/src/plugins/content_management/public/content_client/content_client_context.tsx index 0685c6acf74ed..b2335ed9b6bdb 100644 --- a/src/plugins/content_management/public/content_client/content_client_context.tsx +++ b/src/plugins/content_management/public/content_client/content_client_context.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { QueryClientProvider } from '@tanstack/react-query'; import type { ContentClient } from './content_client'; @@ -18,10 +18,11 @@ export const useContentClient = (): ContentClient => { return contentClient; }; -export const ContentClientProvider: React.FC<{ contentClient: ContentClient }> = ({ - contentClient, - children, -}) => { +export const ContentClientProvider: FC< + PropsWithChildren<{ + contentClient: ContentClient; + }> +> = ({ contentClient, children }) => { return ( {children} diff --git a/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx b/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx index 6f19801c2c376..b16e5dc5be72e 100644 --- a/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx +++ b/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { ContentClientProvider } from './content_client_context'; import { ContentClient } from './content_client'; @@ -28,7 +28,7 @@ const setup = () => { }); const contentClient = new ContentClient(() => crudClient, contentTypeRegistry); - const Wrapper: React.FC = ({ children }) => ( + const Wrapper: FC = ({ children }) => ( {children} ); diff --git a/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx b/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx index 59c04ede3ab42..536dbf0aa6fd2 100644 --- a/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx +++ b/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { ContentClientProvider } from './content_client_context'; import { ContentClient } from './content_client'; @@ -24,7 +24,7 @@ const setup = () => { }); const contentClient = new ContentClient(() => crudClient, contentTypeRegistry); - const Wrapper: React.FC = ({ children }) => ( + const Wrapper: FC = ({ children }) => ( {children} ); diff --git a/src/plugins/custom_integrations/public/mocks.tsx b/src/plugins/custom_integrations/public/mocks.tsx index 2503008ea90ec..d21eb1bbc3e8b 100644 --- a/src/plugins/custom_integrations/public/mocks.tsx +++ b/src/plugins/custom_integrations/public/mocks.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { coreMock } from '@kbn/core/public/mocks'; import { CustomIntegrationsSetup, CustomIntegrationsStart } from './types'; import { CustomIntegrationsServicesProvider } from './services'; @@ -25,7 +25,7 @@ function createCustomIntegrationsStart(): jest.Mocked { return { languageClientsUiComponents: {}, - ContextProvider: jest.fn(({ children }) => ( + ContextProvider: jest.fn(({ children }: PropsWithChildren) => ( {children} diff --git a/src/plugins/custom_integrations/public/plugin.tsx b/src/plugins/custom_integrations/public/plugin.tsx index fce79654bd52a..c1de44473aa7b 100755 --- a/src/plugins/custom_integrations/public/plugin.tsx +++ b/src/plugins/custom_integrations/public/plugin.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { @@ -71,7 +71,7 @@ export class CustomIntegrationsPlugin })), }; - const ContextProvider: React.FC = ({ children }) => ( + const ContextProvider: FC = ({ children }) => ( {children} diff --git a/src/plugins/custom_integrations/public/services/index.tsx b/src/plugins/custom_integrations/public/services/index.tsx index ad343a96390b0..dac34dd0e8c0b 100644 --- a/src/plugins/custom_integrations/public/services/index.tsx +++ b/src/plugins/custom_integrations/public/services/index.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { createContext, FC, useContext } from 'react'; +import React, { createContext, FC, PropsWithChildren, useContext } from 'react'; import { CustomIntegrationsFindService } from './find'; import { CustomIntegrationsPlatformService } from './platform'; @@ -29,10 +29,9 @@ const CustomIntegrationsServicesContext = createContext = ({ - children, - ...services -}) => ( +export const CustomIntegrationsServicesProvider: FC< + PropsWithChildren +> = ({ children, ...services }) => ( {children} diff --git a/src/plugins/custom_integrations/public/types.ts b/src/plugins/custom_integrations/public/types.ts index 60b8aefe23dd1..cd1f150ccaddb 100755 --- a/src/plugins/custom_integrations/public/types.ts +++ b/src/plugins/custom_integrations/public/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { FC, PropsWithChildren } from 'react'; import { CustomIntegration } from '../common'; export interface CustomIntegrationsSetup { @@ -14,8 +15,8 @@ export interface CustomIntegrationsSetup { } export interface CustomIntegrationsStart { - ContextProvider: React.FC; - languageClientsUiComponents: Record; + ContextProvider: FC; + languageClientsUiComponents: Record; } // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx index 4da2d77825f47..64d29f04a42ae 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { act } from 'react-dom/test-utils'; import { mount, ReactWrapper } from 'enzyme'; import { I18nProvider } from '@kbn/i18n-react'; @@ -27,7 +27,7 @@ jest.mock('@kbn/content-management-table-list-view-table', () => { return { __esModule: true, ...originalModule, - TableListViewKibanaProvider: jest.fn().mockImplementation(({ children }) => { + TableListViewKibanaProvider: jest.fn().mockImplementation(({ children }: PropsWithChildren) => { return <>{children}; }), }; diff --git a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels.tsx b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels.tsx index c878090ec7c1b..83a4abc30d7fe 100644 --- a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels.tsx +++ b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels.tsx @@ -13,6 +13,8 @@ import React, { useCallback, useMemo, useLayoutEffect, + FC, + PropsWithChildren, } from 'react'; import { EuiFlexGroup, EuiFlexGroupProps } from '@elastic/eui'; @@ -48,7 +50,7 @@ export interface Props { gutterSize?: EuiFlexGroupProps['gutterSize']; } -export const Panels: React.FC = ({ maxWidth, flyoutClassName, ...props }) => { +export const Panels: FC> = ({ maxWidth, flyoutClassName, ...props }) => { const flyoutDOMelement = useMemo(() => { const el = document.getElementsByClassName(flyoutClassName); diff --git a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx index a25d4a03a83c8..ff36dcc45b063 100644 --- a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx +++ b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx @@ -5,11 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { useEffect } from 'react'; +import React, { useEffect, FC, PropsWithChildren } from 'react'; import { useFlyoutPanelContext } from './flyout_panel'; -export const PanelContent: React.FC = (props) => { +export const PanelContent: FC = (props) => { const { registerContent } = useFlyoutPanelContext(); useEffect(() => { diff --git a/src/plugins/data_view_field_editor/public/components/field_editor_context.tsx b/src/plugins/data_view_field_editor/public/components/field_editor_context.tsx index 494d6034f6669..98d8b7ecd215a 100644 --- a/src/plugins/data_view_field_editor/public/components/field_editor_context.tsx +++ b/src/plugins/data_view_field_editor/public/components/field_editor_context.tsx @@ -6,7 +6,13 @@ * Side Public License, v 1. */ -import React, { createContext, useContext, FunctionComponent, useMemo } from 'react'; +import React, { + createContext, + useContext, + FunctionComponent, + useMemo, + PropsWithChildren, +} from 'react'; import { NotificationsStart, CoreStart } from '@kbn/core/public'; import type { BehaviorSubject } from 'rxjs'; import type { @@ -54,7 +60,7 @@ export interface Context { const fieldEditorContext = createContext(undefined); -export const FieldEditorProvider: FunctionComponent = ({ +export const FieldEditorProvider: FunctionComponent> = ({ services, dataView, links, diff --git a/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels.tsx b/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels.tsx index 80d697e78e03c..a40da7dadeb15 100644 --- a/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels.tsx +++ b/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels.tsx @@ -54,6 +54,7 @@ export interface Props { gutterSize?: EuiFlexGroupProps['gutterSize']; /** Flag to indicate if the panels width are declared as fixed pixel width instead of percent */ fixedPanelWidths?: boolean; + children: React.ReactNode; } export const Panels: React.FC = ({ diff --git a/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels_content.tsx b/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels_content.tsx index b77e55c7a7148..8049ddbaf5218 100644 --- a/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels_content.tsx +++ b/src/plugins/data_view_field_editor/public/components/flyout_panels/flyout_panels_content.tsx @@ -9,7 +9,7 @@ import React, { useEffect } from 'react'; import { useFlyoutPanelContext } from './flyout_panel'; -export const PanelContent: React.FC = (props) => { +export const PanelContent: React.FC<{ children: React.ReactNode }> = (props) => { const { registerContent } = useFlyoutPanelContext(); useEffect(() => { diff --git a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx index c89473c49b7d1..18a9c30e3cc47 100644 --- a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx +++ b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx @@ -14,7 +14,8 @@ import React, { useCallback, useEffect, useRef, - FunctionComponent, + FC, + PropsWithChildren, } from 'react'; import { renderToString } from 'react-dom/server'; import useDebounce from 'react-use/lib/useDebounce'; @@ -64,10 +65,11 @@ const documentsSelector = (state: PreviewState) => { }; }; -export const FieldPreviewProvider: FunctionComponent<{ controller: PreviewController }> = ({ - controller, - children, -}) => { +export const FieldPreviewProvider: FC< + PropsWithChildren<{ + controller: PreviewController; + }> +> = ({ controller, children }) => { const { dataView, services: { diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx index 8b12ed59ed6fd..95a4dae981955 100644 --- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx +++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton, EuiButtonEmpty, EuiPageHeader } from '@elastic/eui'; import { DataView } from '@kbn/data-views-plugin/public'; @@ -46,7 +46,7 @@ const removeTooltip = i18n.translate('indexPatternManagement.editDataView.remove defaultMessage: 'Delete', }); -export const IndexHeader: React.FC = ({ +export const IndexHeader: FC> = ({ defaultIndex, indexPattern, setDefault, diff --git a/src/plugins/discover/public/application/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx index f0dc48a1905e7..875b4241d314d 100644 --- a/src/plugins/discover/public/application/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment, useCallback, useMemo, useState } from 'react'; +import React, { Fragment, useCallback, useMemo, useState, FC, PropsWithChildren } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiSpacer, EuiText, useEuiPaddingSize } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -242,7 +242,7 @@ export function ContextAppContent({ ); } -const WrapperWithPadding: React.FC = ({ children }) => { +const WrapperWithPadding: FC = ({ children }) => { const padding = useEuiPaddingSize('s'); return ( diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable_base.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable_base.tsx index 2e883198076dd..b82e582fc8f74 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable_base.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable_base.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { css } from '@emotion/react'; import { EuiFlexGroup, EuiFlexItem, EuiProgress } from '@elastic/eui'; import { @@ -29,7 +29,7 @@ export interface SavedSearchEmbeddableBaseProps { interceptedWarnings?: SearchResponseWarning[]; } -export const SavedSearchEmbeddableBase: React.FC = ({ +export const SavedSearchEmbeddableBase: FC> = ({ isLoading, totalHitCount, prepend, diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx b/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx index 5464d1967124c..28495774d2c3b 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx @@ -14,6 +14,8 @@ import React, { useMemo, useEffect, useRef, + FC, + PropsWithChildren, } from 'react'; import { EuiFlyout } from '@elastic/eui'; @@ -39,7 +41,7 @@ const DEFAULT_FLYOUT_PROPS = { maxWidth: 500, }; -export const GlobalFlyoutProvider: React.FC = ({ children }) => { +export const GlobalFlyoutProvider: FC = ({ children }) => { const [showFlyout, setShowFlyout] = useState(false); const [activeContent, setActiveContent] = useState | undefined>(undefined); diff --git a/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx index bac5d85842900..c3f1ef25545d8 100644 --- a/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx +++ b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiLoadingSpinner, EuiText, EuiPageTemplate } from '@elastic/eui'; -export const PageLoading: React.FunctionComponent = ({ children }) => { +export const PageLoading: FC = ({ children }) => { return ( } diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx index 1f5a249bb1465..a6faefdf9a22f 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { useState, useContext, createContext } from 'react'; +import React, { useState, useContext, createContext, FC, PropsWithChildren } from 'react'; import { EuiSpacer, EuiText, EuiTextColor, EuiButton } from '@elastic/eui'; import { TextField, NumericField } from '../../../components'; @@ -48,7 +48,7 @@ const useGlobalFields = () => { return ctx; }; -const FormGlobalFields: React.FC = ({ children }) => { +const FormGlobalFields: FC = ({ children }) => { return ( {(fields) => { @@ -170,7 +170,7 @@ const useGlobalFields = () => { return ctx; }; -const FormGlobalFields: React.FC = ({ children }) => { +const FormGlobalFields: FC = ({ children }) => { return ( {(fields) => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_utils.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_utils.tsx index e72f7600031c7..3273457a42b4d 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_utils.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_utils.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiSpacer, EuiButton } from '@elastic/eui'; import { action } from '@storybook/addon-actions'; @@ -30,7 +30,7 @@ export interface FormWrapperProps { formConfig?: FormConfig; } -export const FormWrapper: FC = ({ formConfig, children }) => { +export const FormWrapper: FC> = ({ formConfig, children }) => { const { form } = useForm(formConfig); return ( diff --git a/src/plugins/files_management/public/context.tsx b/src/plugins/files_management/public/context.tsx index 0688c5a7edecb..6edf9b4649929 100644 --- a/src/plugins/files_management/public/context.tsx +++ b/src/plugins/files_management/public/context.tsx @@ -6,13 +6,13 @@ * Side Public License, v 1. */ -import React, { createContext, useContext, FC } from 'react'; +import React, { createContext, useContext, FC, PropsWithChildren } from 'react'; import type { AppContext } from './types'; const FilesManagementAppContext = createContext(null as unknown as AppContext); -export const FilesManagementAppContextProvider: FC = ({ +export const FilesManagementAppContextProvider: FC> = ({ children, filesClient, getFileKindDefinition, diff --git a/src/plugins/interactive_setup/public/plugin.tsx b/src/plugins/interactive_setup/public/plugin.tsx index 84c581fe44a9a..5c6e02b05d565 100644 --- a/src/plugins/interactive_setup/public/plugin.tsx +++ b/src/plugins/interactive_setup/public/plugin.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import ReactDOM from 'react-dom'; @@ -52,7 +52,7 @@ export interface ProvidersProps { defaultCode?: string; } -export const Providers: FunctionComponent = ({ +export const Providers: FC> = ({ defaultCode, services, children, diff --git a/src/plugins/interactive_setup/public/text_truncate.tsx b/src/plugins/interactive_setup/public/text_truncate.tsx index 32736e80211ae..16fb12d5cb4c5 100644 --- a/src/plugins/interactive_setup/public/text_truncate.tsx +++ b/src/plugins/interactive_setup/public/text_truncate.tsx @@ -7,10 +7,10 @@ */ import { EuiToolTip } from '@elastic/eui'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useLayoutEffect, useRef, useState } from 'react'; -export const TextTruncate: FunctionComponent = ({ children }) => { +export const TextTruncate: FC = ({ children }) => { const textRef = useRef(null); const [showTooltip, setShowTooltip] = useState(false); diff --git a/src/plugins/interactive_setup/public/use_verification.tsx b/src/plugins/interactive_setup/public/use_verification.tsx index 42bcf94ad1f8c..febac9ddf73ef 100644 --- a/src/plugins/interactive_setup/public/use_verification.tsx +++ b/src/plugins/interactive_setup/public/use_verification.tsx @@ -8,7 +8,7 @@ import { EuiModal, EuiModalHeader } from '@elastic/eui'; import constate from 'constate'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useEffect, useRef, useState } from 'react'; import { euiThemeVars } from '@kbn/ui-theme'; @@ -38,7 +38,7 @@ const [OuterVerificationProvider, useVerification] = constate( } ); -const InnerVerificationProvider: FunctionComponent = ({ children }) => { +const InnerVerificationProvider: FC = ({ children }) => { const { http } = useKibana(); const { status, setStatus, setCode } = useVerification(); @@ -72,7 +72,7 @@ const InnerVerificationProvider: FunctionComponent = ({ children }) => { ); }; -export const VerificationProvider: FunctionComponent = ({ +export const VerificationProvider: FC> = ({ defaultCode, children, }) => { diff --git a/src/plugins/kibana_react/public/context/context.tsx b/src/plugins/kibana_react/public/context/context.tsx index 8c32bdab69b31..0a5e0ad0faa91 100644 --- a/src/plugins/kibana_react/public/context/context.tsx +++ b/src/plugins/kibana_react/public/context/context.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { KibanaReactContext, KibanaReactContextValue, KibanaServices } from './types'; import { createReactOverlays } from '../overlays'; import { createNotifications } from '../notifications'; @@ -28,8 +28,8 @@ export const useKibana = (): KibanaReactContextValue< export const withKibana = }>( type: React.ComponentType -): React.FC> => { - const EnhancedType: React.FC> = (props: Omit) => { +): FC> => { + const EnhancedType: FC> = (props: Omit) => { const kibana = useKibana(); return React.createElement(type, { ...props, kibana } as Props); }; @@ -45,7 +45,7 @@ export const createKibanaReactContext = ( notifications: createNotifications(services), }; - const Provider: React.FC<{ services?: Services }> = ({ + const Provider: FC> = ({ services: newServices = {}, children, }) => { diff --git a/src/plugins/kibana_react/public/context/types.ts b/src/plugins/kibana_react/public/context/types.ts index 4962267974d79..f0be584ae282c 100644 --- a/src/plugins/kibana_react/public/context/types.ts +++ b/src/plugins/kibana_react/public/context/types.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { CoreStart } from '@kbn/core/public'; import { KibanaReactOverlays } from '../overlays'; import { KibanaReactNotifications } from '../notifications'; @@ -21,6 +21,6 @@ export interface KibanaReactContextValue { export interface KibanaReactContext { value: KibanaReactContextValue; - Provider: React.FC<{ services?: T }>; + Provider: FC>; Consumer: React.Consumer>; } diff --git a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx index cc75e898314dd..6204922a95a1f 100644 --- a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx +++ b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { Observable } from 'rxjs'; import { EuiProviderProps } from '@elastic/eui'; @@ -16,9 +16,12 @@ import { KibanaThemeProvider as KbnThemeProvider } from '@kbn/react-kibana-conte export interface KibanaThemeProviderProps { theme$: Observable; modify?: EuiProviderProps<{}>['modify']; + children: React.ReactNode; } /** @deprecated use `KibanaThemeProvider` from `@kbn/react-kibana-context-theme */ -export const KibanaThemeProvider: FC = ({ theme$, modify, children }) => ( - {children} -); +export const KibanaThemeProvider: FC> = ({ + theme$, + modify, + children, +}) => {children}; diff --git a/src/plugins/presentation_util/public/services/create/provider.tsx b/src/plugins/presentation_util/public/services/create/provider.tsx index 0cebcce5e9572..4844087298003 100644 --- a/src/plugins/presentation_util/public/services/create/provider.tsx +++ b/src/plugins/presentation_util/public/services/create/provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, FC, PropsWithChildren } from 'react'; import { PluginServiceFactory } from './factory'; /** @@ -62,7 +62,7 @@ export class PluginServiceProvider< private _requiredServices?: RequiredServices; private context = createContext(null); private pluginService: Service | null = null; - public readonly Provider: React.FC = ({ children }) => { + public readonly Provider: FC = ({ children }) => { return {children}; }; diff --git a/src/plugins/presentation_util/public/services/create/registry.tsx b/src/plugins/presentation_util/public/services/create/registry.tsx index 056822408f8be..8b0b2d4d194d7 100644 --- a/src/plugins/presentation_util/public/services/create/registry.tsx +++ b/src/plugins/presentation_util/public/services/create/registry.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { PluginServiceProvider, PluginServiceProviders } from './provider'; import { PluginServiceProvidersMediator } from './providers_mediator'; @@ -58,7 +58,7 @@ export class PluginServiceRegistry< // Collect and combine Context.Provider elements from each Service Provider into a single // Functional Component. - const provider: React.FC = ({ children }) => ( + const provider: FC = ({ children }) => ( <> {values.reduceRight((acc, serviceProvider) => { return {acc}; diff --git a/src/plugins/presentation_util/public/types.ts b/src/plugins/presentation_util/public/types.ts index dfc81ad4a0a27..0476c0dca1fe4 100644 --- a/src/plugins/presentation_util/public/types.ts +++ b/src/plugins/presentation_util/public/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { FC, PropsWithChildren } from 'react'; import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; @@ -16,7 +17,7 @@ import { PresentationLabsService } from './services/labs/types'; export interface PresentationUtilPluginSetup {} export interface PresentationUtilPluginStart { - ContextProvider: React.FC; + ContextProvider: FC; labsService: PresentationLabsService; registerExpressionsLanguage: typeof registerExpressionsLanguage; } diff --git a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx index a58848f06c980..b930f51f37bb3 100644 --- a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; @@ -32,7 +32,7 @@ interface MinimalSaveModalProps { export function showSaveModal( saveModal: React.ReactElement, - Wrapper?: React.FC + Wrapper?: FC ) { const container = document.createElement('div'); const closeModal = () => { diff --git a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx index fe11eccbf8614..72632f078620f 100644 --- a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx +++ b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { lazy, Suspense } from 'react'; +import React, { lazy, Suspense, FC, PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { i18n } from '@kbn/i18n'; @@ -43,7 +43,7 @@ export const mountManagementSection = async ({ core, mountParams }: MountParams) coreStart.chrome.docTitle.change(title); - const RedirectToHomeIfUnauthorized: React.FunctionComponent = ({ children }) => { + const RedirectToHomeIfUnauthorized: FC = ({ children }) => { const allowed = capabilities?.management?.kibana?.objects ?? false; if (!allowed) { diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/button_submit/button_submit.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/button_submit/button_submit.tsx index 6902c7f222a1f..983945f0b246f 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/button_submit/button_submit.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/button_submit/button_submit.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiButton } from '@elastic/eui'; export interface ButtonSubmitProps { @@ -14,7 +14,11 @@ export interface ButtonSubmitProps { onClick: () => void; } -export const ButtonSubmit: React.FC = ({ disabled, onClick, children }) => { +export const ButtonSubmit: FC> = ({ + disabled, + onClick, + children, +}) => { return ( = ({ +export const DrilldownForm: FC> = ({ name = '', onNameChange, triggers, diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx index 6cf6420674868..4d7b006069f8b 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlyoutHeader, EuiTitle, @@ -30,7 +30,7 @@ export interface FlyoutFrameProps { /** * @todo This component can be moved to `kibana_react`. */ -export const FlyoutFrame: React.FC = ({ +export const FlyoutFrame: FC> = ({ title = '', footer, onClose, diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/text_with_icon/text_with_icon.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/text_with_icon/text_with_icon.tsx index 03cf65db41567..dbbd3ad9ce53a 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/text_with_icon/text_with_icon.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/text_with_icon/text_with_icon.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiTextColor, EuiTextColorProps, @@ -24,7 +24,7 @@ export interface TextWithIconProps { iconTooltip?: React.ReactNode; } -export const TextWithIcon: React.FC = ({ +export const TextWithIcon: FC> = ({ color, tooltip, icon, diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_line_item/trigger_line_item.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_line_item/trigger_line_item.tsx index 3bd269d219639..15fad202cdb07 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_line_item/trigger_line_item.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_line_item/trigger_line_item.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { i18n } from '@kbn/i18n'; import { TextWithIcon } from '../text_with_icon'; @@ -22,7 +22,7 @@ export interface TriggerLineItemProps { incompatible?: boolean; } -export const TriggerLineItem: React.FC = ({ +export const TriggerLineItem: FC> = ({ tooltip, incompatible, children, diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/context/context.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/context/context.tsx index e8249d194b089..2efb07d24f645 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/context/context.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/context/context.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { PropsWithChildren } from 'react'; import { DrilldownManagerState, DrilldownManagerStateDeps } from '../../state'; const context = React.createContext(null); @@ -15,10 +15,9 @@ export const useDrilldownManager = () => React.useContext(context)!; export type DrilldownManagerProviderProps = DrilldownManagerStateDeps; -export const DrilldownManagerProvider: React.FC = ({ - children, - ...deps -}) => { +export const DrilldownManagerProvider: React.FC< + PropsWithChildren +> = ({ children, ...deps }) => { // eslint-disable-next-line react-hooks/exhaustive-deps const value = React.useMemo(() => new DrilldownManagerState(deps), []); diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx index be660c6989637..ce22bffe748c6 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useDrilldownManager } from '../context'; -export const DrilldownManagerFooter: React.FC = ({ children }) => { +export const DrilldownManagerFooter: FC = ({ children }) => { const drilldowns = useDrilldownManager(); React.useEffect(() => { drilldowns.setFooter(children); diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_title/drilldown_manager_title.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_title/drilldown_manager_title.tsx index 18eac9bdfed1c..82de859f5388b 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_title/drilldown_manager_title.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_title/drilldown_manager_title.tsx @@ -9,7 +9,7 @@ import * as React from 'react'; import { useDrilldownManager } from '../context'; -export const DrilldownManagerTitle: React.FC = ({ children }) => { +export const DrilldownManagerTitle: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const drilldowns = useDrilldownManager(); React.useEffect(() => { drilldowns.setTitle(children); diff --git a/src/plugins/usage_collection/public/plugin.tsx b/src/plugins/usage_collection/public/plugin.tsx index 635e33f8fd0b0..3bd66b7370620 100644 --- a/src/plugins/usage_collection/public/plugin.tsx +++ b/src/plugins/usage_collection/public/plugin.tsx @@ -9,7 +9,7 @@ import { Reporter, ApplicationUsageTracker } from '@kbn/analytics'; import type { UiCounterMetricType } from '@kbn/analytics'; import type { Subscription } from 'rxjs'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { PluginInitializerContext, Plugin, @@ -74,7 +74,7 @@ export interface UsageCollectionSetup { * } * ``` */ - ApplicationUsageTrackingProvider: React.FC; + ApplicationUsageTrackingProvider: FC; }; /** Report whenever a UI event occurs for UI counters to report it **/ diff --git a/x-pack/examples/triggers_actions_ui_example/public/components/page.tsx b/x-pack/examples/triggers_actions_ui_example/public/components/page.tsx index 4a16528bc2d06..a03712f772341 100644 --- a/x-pack/examples/triggers_actions_ui_example/public/components/page.tsx +++ b/x-pack/examples/triggers_actions_ui_example/public/components/page.tsx @@ -14,6 +14,7 @@ interface PageProps { title: string; crumb?: string; isHome?: boolean; + children: React.ReactNode; } export const Page: React.FC = (props) => { diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/components/page/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/components/page/index.tsx index 66b68b877da1c..1640eabdf91d7 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/components/page/index.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/components/page/index.tsx @@ -9,6 +9,7 @@ import * as React from 'react'; import { EuiPageBody, EuiPageTemplate, EuiPageSection, EuiPageHeader } from '@elastic/eui'; export interface PageProps { + children: React.ReactNode; title?: React.ReactNode; } diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/components/section/section.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/components/section/section.tsx index 8f5303d816678..a2c9541dd6dcb 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/components/section/section.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/components/section/section.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiTitle, EuiSpacer } from '@elastic/eui'; export interface Props { + children: React.ReactNode; title: React.ReactNode; } diff --git a/x-pack/packages/ml/aiops_components/src/log_rate_analysis_state_provider/log_rate_analysis_state_provider.tsx b/x-pack/packages/ml/aiops_components/src/log_rate_analysis_state_provider/log_rate_analysis_state_provider.tsx index f3aa55bdce771..72289fe0b75cf 100644 --- a/x-pack/packages/ml/aiops_components/src/log_rate_analysis_state_provider/log_rate_analysis_state_provider.tsx +++ b/x-pack/packages/ml/aiops_components/src/log_rate_analysis_state_provider/log_rate_analysis_state_provider.tsx @@ -11,6 +11,7 @@ import React, { useMemo, useState, type FC, + type PropsWithChildren, type Dispatch, type SetStateAction, } from 'react'; @@ -65,7 +66,9 @@ interface LogRateAnalysisStateProviderProps { * including children components to be wrapped by the Provider. * @returns A context provider wrapping children with access to log rate analysis state. */ -export const LogRateAnalysisStateProvider: FC = (props) => { +export const LogRateAnalysisStateProvider: FC< + PropsWithChildren +> = (props) => { const { children, initialAnalysisStart: incomingInitialAnalysisStart } = props; const [autoRunAnalysis, setAutoRunAnalysis] = useState(true); diff --git a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx index 1dcc35a433eb2..8fff372570505 100644 --- a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx +++ b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { useEuiTheme, @@ -49,7 +49,7 @@ interface ProgressControlProps { * @param props ProgressControls component props * @returns The ProgressControls component. */ -export const ProgressControls: FC = (props) => { +export const ProgressControls: FC> = (props) => { const { children, isBrushCleared, diff --git a/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx b/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx index f9d189167df9b..035e89991d0f3 100644 --- a/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx +++ b/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx @@ -7,6 +7,7 @@ import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; +import type { PropsWithChildren } from 'react'; import React from 'react'; import { EuiSuperDatePicker } from '@elastic/eui'; @@ -26,10 +27,10 @@ jest.mock('@elastic/eui', () => { const EuiSuperDatePickerMock = jest.fn(() => { return null; }); - const EuiFlexGroupMock = jest.fn(({ children }) => { + const EuiFlexGroupMock = jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }); - const EuiFlexItemMock = jest.fn(({ children }) => { + const EuiFlexItemMock = jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }); return { diff --git a/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx b/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx index 49b090ef58983..e544ad9826226 100644 --- a/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx +++ b/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { createContext, useContext, type FC } from 'react'; +import React, { createContext, useContext, type FC, type PropsWithChildren } from 'react'; import type { UI_SETTINGS } from '@kbn/data-plugin/common'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -78,7 +78,7 @@ export const useDatePickerContext = (): DatePickerDependencies => { * @returns {React.ReactElement} The DatePickerContextProvider component. */ -export const DatePickerContextProvider: FC = (props) => { +export const DatePickerContextProvider: FC> = (props) => { const { children, ...deps } = props; return {children}; }; diff --git a/x-pack/packages/ml/url_state/src/url_state.tsx b/x-pack/packages/ml/url_state/src/url_state.tsx index ac34f0ad4cb76..670da0cb42724 100644 --- a/x-pack/packages/ml/url_state/src/url_state.tsx +++ b/x-pack/packages/ml/url_state/src/url_state.tsx @@ -14,6 +14,7 @@ import React, { useRef, useEffect, type FC, + type PropsWithChildren, } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { isEqual } from 'lodash'; @@ -91,7 +92,7 @@ export const urlStateStore = createContext({ export const { Provider } = urlStateStore; -export const UrlStateProvider: FC = ({ children }) => { +export const UrlStateProvider: FC = ({ children }) => { const history = useHistory(); const { search: searchString } = useLocation(); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx index 6bf41d9f18b7f..59e0c83cebd94 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx @@ -7,7 +7,7 @@ import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks'; import { renderHook } from '@testing-library/react-hooks'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { DataQualityProvider, useDataQualityContext } from '.'; @@ -19,7 +19,7 @@ const mockTelemetryEvents = { reportDataQualityIndexChecked: mockReportDataQualityIndexChecked, reportDataQualityCheckAllCompleted: mockReportDataQualityCheckAllClicked, }; -const ContextWrapper: React.FC = ({ children }) => ( +const ContextWrapper: FC = ({ children }) => ( (undefined); -export const DataQualityProvider: React.FC = ({ +export const DataQualityProvider: React.FC> = ({ children, httpFetch, toasts, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_mappings/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_mappings/index.test.tsx index b7e0854b46443..55b2c93c07577 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_mappings/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_mappings/index.test.tsx @@ -6,7 +6,7 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { DataQualityProvider } from '../data_quality_panel/data_quality_context'; import { mockMappingsResponse } from '../mock/mappings_response/mock_mappings_response'; @@ -23,7 +23,7 @@ const mockTelemetryEvents = { }; const { toasts } = notificationServiceMock.createSetupContract(); -const ContextWrapper: React.FC = ({ children }) => ( +const ContextWrapper: FC = ({ children }) => ( ( +const ContextWrapper: FC = ({ children }) => ( ( ); -const ContextWrapperILMNotAvailable: React.FC = ({ children }) => ( +const ContextWrapperILMNotAvailable: FC = ({ children }) => ( ( +const ContextWrapper: FC = ({ children }) => ( (mockCoreStart); -export const NavigationProvider: React.FC = ({ children }) => ( +export const NavigationProvider: FC = ({ children }) => ( {children} ); diff --git a/x-pack/packages/security-solution/navigation/src/context.tsx b/x-pack/packages/security-solution/navigation/src/context.tsx index 4daff491cffda..85acef13337a4 100644 --- a/x-pack/packages/security-solution/navigation/src/context.tsx +++ b/x-pack/packages/security-solution/navigation/src/context.tsx @@ -4,14 +4,16 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useContext, createContext } from 'react'; import type { CoreStart } from '@kbn/core/public'; const navigationContext = createContext(null); -export const NavigationProvider: React.FC<{ core: CoreStart }> = ({ core, children }) => ( - {children} -); +export const NavigationProvider: FC> = ({ + core, + children, +}) => {children}; export const useNavigationContext = (): CoreStart => { const services = useContext(navigationContext); diff --git a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx index 7e6bac2510bdf..f99b8ca88694c 100644 --- a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx +++ b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiTitle, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -36,49 +37,46 @@ const useLinkIconStyles = () => { }; }; -export const LandingLinkIcon: React.FC = React.memo(function LandingLinkIcon({ - item, - urlState, - onLinkClick, - children, -}) { - const styles = useLinkIconStyles(); - const { title, description, landingIcon, isBeta, betaOptions } = item; +export const LandingLinkIcon: FC> = React.memo( + function LandingLinkIcon({ item, urlState, onLinkClick, children }) { + const styles = useLinkIconStyles(); + const { title, description, landingIcon, isBeta, betaOptions } = item; - return ( - - - - - - - - - {title} - - - {isBeta && ( + return ( + + + + + + - + + {title} + - )} - - - - - {description} - - {children} - - ); -}); + {isBeta && ( + + + + )} + + + + + {description} + + {children} + + ); + } +); const linkIconContainerStyles = css` min-width: 22em; diff --git a/x-pack/packages/security-solution/side_nav/src/telemetry/telemetry_context.tsx b/x-pack/packages/security-solution/side_nav/src/telemetry/telemetry_context.tsx index aec5460ddc67a..615a92dd3620e 100644 --- a/x-pack/packages/security-solution/side_nav/src/telemetry/telemetry_context.tsx +++ b/x-pack/packages/security-solution/side_nav/src/telemetry/telemetry_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { createContext, useContext } from 'react'; import type { Tracker } from '../types'; @@ -15,7 +15,10 @@ interface TelemetryProviderProps { const TelemetryContext = createContext<{ tracker?: Tracker } | null>(null); -export const TelemetryContextProvider: FC = ({ children, tracker }) => { +export const TelemetryContextProvider: FC> = ({ + children, + tracker, +}) => { return {children}; }; diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx index 75f4820316e30..bf977c4f2a399 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { type DataViewField } from '@kbn/data-views-plugin/public'; import { startWith } from 'rxjs'; @@ -99,7 +99,9 @@ export const useChangePointDetectionControlsContext = () => { return useContext(ChangePointDetectionControlsContext); }; -export const ChangePointDetectionControlsContextProvider: FC = ({ children }) => { +export const ChangePointDetectionControlsContextProvider: FC = ({ + children, +}) => { const { dataView } = useDataSource(); const metricFieldOptions = useMemo(() => { @@ -127,7 +129,7 @@ export const ChangePointDetectionControlsContextProvider: FC = ({ children }) => ); }; -export const ChangePointDetectionContextProvider: FC = ({ children }) => { +export const ChangePointDetectionContextProvider: FC = ({ children }) => { const { dataView, savedSearch } = useDataSource(); const { uiSettings, diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx index bc93bbbff08fb..d3f56a4dcc733 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC, useCallback, useMemo, useState } from 'react'; +import React, { type FC, type PropsWithChildren, useCallback, useMemo, useState } from 'react'; import { EuiButton, EuiButtonIcon, @@ -631,7 +631,11 @@ interface FieldsControlsProps { /** * Renders controls for fields selection and emits updates on change. */ -export const FieldsControls: FC = ({ fieldConfig, onChange, children }) => { +export const FieldsControls: FC> = ({ + fieldConfig, + onChange, + children, +}) => { const { splitFieldsOptions, combinedQuery } = useChangePointDetectionContext(); const { dataView } = useDataSource(); const { data, uiSettings, fieldFormats, charts, fieldStats } = useAiopsAppContext(); diff --git a/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx b/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx index e57c9317c4c9a..15c561f042f77 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { css } from '@emotion/react'; @@ -61,7 +61,7 @@ export const ExpandedRow: FC = ({ category, displayExamples = ); }; -const Section: FC<{ title: string }> = ({ title, children }) => { +const Section: FC> = ({ title, children }) => { return ( <> diff --git a/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx index 895d28e3256ac..04bac15bc9bdc 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useCallback, useMemo } from 'react'; import { EuiText, EuiHorizontalRule } from '@elastic/eui'; import type { SerializedStyles } from '@emotion/react'; @@ -175,7 +175,7 @@ export const FormattedTokens: FC = ({ category }) => { ); }; -const WrapInText: FC = ({ children }) => ( +const WrapInText: FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts index 72a5ed494a446..ae803d312e59e 100644 --- a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts +++ b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createContext, type FC, useContext } from 'react'; +import { createContext, type FC, type PropsWithChildren, useContext } from 'react'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -119,12 +119,14 @@ export interface AiopsAppDependencies { renderOption: EuiComboBoxProps['renderOption']; closeFlyout: () => void; }; - FieldStatsFlyoutProvider: FC<{ - dataView: DataView; - fieldStatsServices: FieldStatsServices; - timeRangeMs?: TimeRangeMs; - dslQuery?: FieldStatsProps['dslQuery']; - }>; + FieldStatsFlyoutProvider: FC< + PropsWithChildren<{ + dataView: DataView; + fieldStatsServices: FieldStatsServices; + timeRangeMs?: TimeRangeMs; + dslQuery?: FieldStatsProps['dslQuery']; + }> + >; }; presentationUtil?: PresentationUtilPluginStart; embeddable?: EmbeddableStart; diff --git a/x-pack/plugins/aiops/public/hooks/use_data_source.tsx b/x-pack/plugins/aiops/public/hooks/use_data_source.tsx index fa48846070ef2..081e10a34de65 100644 --- a/x-pack/plugins/aiops/public/hooks/use_data_source.tsx +++ b/x-pack/plugins/aiops/public/hooks/use_data_source.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; @@ -42,7 +42,7 @@ export interface DataSourceContextProviderProps { * @param children * @constructor */ -export const DataSourceContextProvider: FC = ({ +export const DataSourceContextProvider: FC> = ({ dataViewId, savedSearchId, children, diff --git a/x-pack/plugins/aiops/public/hooks/use_filters_query.tsx b/x-pack/plugins/aiops/public/hooks/use_filters_query.tsx index 70465bd775cf0..26f15bb0ff55e 100644 --- a/x-pack/plugins/aiops/public/hooks/use_filters_query.tsx +++ b/x-pack/plugins/aiops/public/hooks/use_filters_query.tsx @@ -5,7 +5,15 @@ * 2.0. */ -import React, { type FC, createContext, useEffect, useState, useContext, useMemo } from 'react'; +import React, { + type FC, + type PropsWithChildren, + createContext, + useEffect, + useState, + useContext, + useMemo, +} from 'react'; import type { Filter, Query, TimeRange } from '@kbn/es-query'; import { useTimeRangeUpdates } from '@kbn/ml-date-picker'; import { type AggregateQuery } from '@kbn/es-query'; @@ -49,10 +57,11 @@ export const FilterQueryContext = createContext<{ * @param children * @constructor */ -export const FilterQueryContextProvider: FC<{ timeRange?: TimeRange }> = ({ - children, - timeRange, -}) => { +export const FilterQueryContextProvider: FC< + PropsWithChildren<{ + timeRange?: TimeRange; + }> +> = ({ children, timeRange }) => { const { data: { query: { filterManager, queryString, timefilter }, diff --git a/x-pack/plugins/aiops/public/hooks/use_reload.tsx b/x-pack/plugins/aiops/public/hooks/use_reload.tsx index 42c3d95e848fb..4d8deae74612b 100644 --- a/x-pack/plugins/aiops/public/hooks/use_reload.tsx +++ b/x-pack/plugins/aiops/public/hooks/use_reload.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useContext } from 'react'; import { type Observable } from 'rxjs'; import useObservable from 'react-use/lib/useObservable'; @@ -17,10 +18,11 @@ export const ReloadContext = React.createContext({ refreshTimestamp: Date.now(), }); -export const ReloadContextProvider: React.FC<{ reload$: Observable }> = ({ - reload$, - children, -}) => { +export const ReloadContextProvider: FC< + PropsWithChildren<{ + reload$: Observable; + }> +> = ({ reload$, children }) => { const refreshTimestamp = useObservable(reload$, Date.now()); return {children}; }; diff --git a/x-pack/plugins/aiops/public/shared_lazy_components.tsx b/x-pack/plugins/aiops/public/shared_lazy_components.tsx index b83a4b3e3ac8e..d25ba022a1f29 100644 --- a/x-pack/plugins/aiops/public/shared_lazy_components.tsx +++ b/x-pack/plugins/aiops/public/shared_lazy_components.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { Suspense } from 'react'; import { EuiErrorBoundary, EuiSkeletonText } from '@elastic/eui'; @@ -20,7 +20,7 @@ const LogRateAnalysisContentWrapperLazy = React.lazy( () => import('./components/log_rate_analysis/log_rate_analysis_content') ); -const LazyWrapper: FC = ({ children }) => ( +const LazyWrapper: FC = ({ children }) => ( }>{children} diff --git a/x-pack/plugins/alerting/public/lib/test_utils.tsx b/x-pack/plugins/alerting/public/lib/test_utils.tsx index 4701cf988de2f..c05d8650832b4 100644 --- a/x-pack/plugins/alerting/public/lib/test_utils.tsx +++ b/x-pack/plugins/alerting/public/lib/test_utils.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { BehaviorSubject } from 'rxjs'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; @@ -29,7 +29,7 @@ export interface AppMockRenderer { render: UiRender; coreStart: CoreStart; queryClient: QueryClient; - AppWrapper: React.FC<{ children: React.ReactElement }>; + AppWrapper: FC; mocked: { setBadge: jest.Mock; }; @@ -78,7 +78,7 @@ export const createAppMockRenderer = ({ setBadge: mockedSetBadge, }, }; - const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( + const AppWrapper = React.memo(({ children }) => ( {children} diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx index 9ff4f6473525b..eb33c47b85770 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { fireEvent, waitFor, within } from '@testing-library/react'; import { useForm, Form } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import { Frequency } from '@kbn/rrule'; @@ -29,7 +29,7 @@ const initialValue: FormProps = { describe('CustomRecurringSchedule', () => { let appMockRenderer: AppMockRenderer; - const MockHookWrapperComponent: React.FC<{ iv?: FormProps }> = ({ + const MockHookWrapperComponent: FC> = ({ children, iv = initialValue, }) => { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.test.tsx index 76390aea7ef18..2606d26568195 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { Frequency } from '@kbn/rrule'; import { fireEvent, within } from '@testing-library/react'; import { useForm, Form } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; @@ -25,7 +25,7 @@ const initialValue: FormProps = { describe('RecurringSchedule', () => { let appMockRenderer: AppMockRenderer; - const MockHookWrapperComponent: React.FC<{ iv?: FormProps }> = ({ + const MockHookWrapperComponent: FC> = ({ children, iv = initialValue, }) => { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx index 7f5906dfc7e00..5e6fe915fcc08 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; import { useForm, Form } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; @@ -17,7 +17,7 @@ import { AppMockRenderer, createAppMockRenderer } from '../../../lib/test_utils' describe('SubmitButton', () => { const onSubmit = jest.fn(); - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm({ defaultValue: { title: 'title' }, schema: { diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.component.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.component.tsx index 603f4679a9e95..1f48965559353 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.component.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.component.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; // @ts-expect-error untyped library import Dropzone from 'react-dropzone'; @@ -16,7 +16,11 @@ export interface Props { onDrop?: (files: FileList) => void; } -export const UploadDropzone: FC = ({ onDrop = () => {}, disabled, children }) => { +export const UploadDropzone: FC> = ({ + onDrop = () => {}, + disabled, + children, +}) => { return ( { +export const UploadDropzone: FC = ({ children }) => { const notify = useNotifyService(); const uploadWorkpad = useImportWorkpad(); const [isDisabled, setIsDisabled] = useState(false); diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx index 3007dc0389885..b9de9013bc015 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { useAutoplayHelper } from './use_autoplay_helper'; import { WorkpadRoutingContext, WorkpadRoutingContextType } from '../workpad_routing_context'; @@ -19,7 +19,7 @@ const getMockedContext = (context: any) => ...context, } as WorkpadRoutingContextType); -const getContextWrapper: (context: WorkpadRoutingContextType) => FC = +const getContextWrapper: (context: WorkpadRoutingContextType) => FC = (context) => ({ children }) => {children}; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx index 0d22783b992ea..0453444f0185e 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { useRefreshHelper } from './use_refresh_helper'; import { WorkpadRoutingContext, WorkpadRoutingContextType } from '../workpad_routing_context'; @@ -29,9 +29,9 @@ const getMockedContext = (context: any) => ...context, } as WorkpadRoutingContextType); -const getContextWrapper: (context: WorkpadRoutingContextType) => FC = - (context) => - ({ children }) => +const getContextWrapper = + (context: WorkpadRoutingContextType) => + ({ children }: PropsWithChildren) => {children}; describe('useRefreshHelper', () => { diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx index 88bec705ed2ee..067359aa00e89 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx @@ -5,7 +5,7 @@ * 2.0. */ import { i18n } from '@kbn/i18n'; -import React, { FC, useEffect } from 'react'; +import React, { FC, PropsWithChildren, useEffect } from 'react'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { getBaseBreadcrumb, getWorkpadBreadcrumb } from '../../lib/breadcrumbs'; @@ -21,7 +21,7 @@ const getWorkpadLabel = () => defaultMessage: 'Workpad', }); -export const WorkpadPresentationHelper: FC = ({ children }) => { +export const WorkpadPresentationHelper: FC = ({ children }) => { const platformService = usePlatformService(); const workpad = useSelector(getWorkpad); useFullscreenPresentationHelper(); diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx index df4b9c4c7474d..0afcae8dc40e6 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, useEffect, useCallback } from 'react'; +import React, { FC, PropsWithChildren, useEffect, useCallback } from 'react'; import { Redirect, useParams } from 'react-router-dom'; import { Routes, Route } from '@kbn/shared-ux-router'; import { useDispatch } from 'react-redux'; @@ -110,7 +110,7 @@ const ExportWorkpadRouteComponent: FC<{ route: WorkpadRouteProps }> = ({ route: ); }; -export const ExportRouteManager: FC = ({ children }) => { +export const ExportRouteManager: FC = ({ children }) => { const params = useParams(); usePageSync(); @@ -123,7 +123,7 @@ export const ExportRouteManager: FC = ({ children }) => { return <>{children}; }; -export const WorkpadHistoryManager: FC = ({ children }) => { +export const WorkpadHistoryManager: FC = ({ children }) => { useRestoreHistory(); useWorkpadHistory(); usePageSync(); diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx index fe90a9e325b7d..39a2f94e175ab 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, createContext } from 'react'; +import React, { FC, PropsWithChildren, createContext } from 'react'; import { useRoutingContext } from './hooks/use_routing_context'; export interface WorkpadRoutingContextType { @@ -46,7 +46,7 @@ export const WorkpadRoutingContext = createContext( basicWorkpadRoutingContext ); -export const WorkpadRoutingContextComponent: FC = ({ children }) => { +export const WorkpadRoutingContextComponent: FC = ({ children }) => { const routingContext = useRoutingContext(); return ( diff --git a/x-pack/plugins/cases/public/client/ui/get_cases_context.tsx b/x-pack/plugins/cases/public/client/ui/get_cases_context.tsx index 8eaa62501db8b..0e7ac1ab67a8d 100644 --- a/x-pack/plugins/cases/public/client/ui/get_cases_context.tsx +++ b/x-pack/plugins/cases/public/client/ui/get_cases_context.tsx @@ -6,7 +6,7 @@ */ import { EuiLoadingSpinner } from '@elastic/eui'; -import type { ReactNode } from 'react'; +import type { ReactNode, PropsWithChildren } from 'react'; import React, { lazy, Suspense } from 'react'; import type { CasesContextProps } from '../../components/cases_context'; @@ -18,9 +18,10 @@ export type GetCasesContextProps = Omit< | 'getFilesClient' >; -const CasesProviderLazy: React.FC<{ value: GetCasesContextPropsInternal }> = lazy( - () => import('../../components/cases_context') -); +const CasesProviderLazy: React.FC<{ + children: React.ReactNode; + value: GetCasesContextPropsInternal; +}> = lazy(() => import('../../components/cases_context')); const CasesProviderLazyWrapper = ({ externalReferenceAttachmentTypeRegistry, @@ -60,8 +61,8 @@ export const getCasesContextLazy = ({ | 'externalReferenceAttachmentTypeRegistry' | 'persistableStateAttachmentTypeRegistry' | 'getFilesClient' ->): (() => React.FC) => { - const CasesProviderLazyWrapperWithRegistry: React.FC = ({ +>): (() => React.FC>) => { + const CasesProviderLazyWrapperWithRegistry: React.FC> = ({ children, ...props }) => ( diff --git a/x-pack/plugins/cases/public/common/test_utils.tsx b/x-pack/plugins/cases/public/common/test_utils.tsx index 65ec29abf90c1..0028d79019f2a 100644 --- a/x-pack/plugins/cases/public/common/test_utils.tsx +++ b/x-pack/plugins/cases/public/common/test_utils.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import type { ReactWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; @@ -48,10 +49,11 @@ interface FormTestComponentProps { formDefaultValue?: Record; onSubmit?: jest.Mock; schema?: FormSchema>; + children: React.ReactNode; } // eslint-disable-next-line react/display-name -export const FormTestComponent: React.FC = ({ +export const FormTestComponent: FC> = ({ children, onSubmit, formDefaultValue, diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx index 7cfc840356355..59b4f012147ee 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx @@ -8,6 +8,7 @@ import { waitFor } from '@testing-library/react'; import { act, renderHook } from '@testing-library/react-hooks'; import userEvent from '@testing-library/user-event'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import AllCasesSelectorModal from '.'; import type { CaseUI } from '../../../../common'; @@ -64,7 +65,7 @@ describe('use cases add to existing case modal hook', () => { const dispatch = jest.fn(); let appMockRender: AppMockRenderer; - const wrapper: React.FC = ({ children }) => { + const wrapper: FC = ({ children }) => { return ( (undefined); -export const CasesProvider: React.FC<{ value: CasesContextProps; queryClient?: QueryClient }> = ({ +export const CasesProvider: FC< + PropsWithChildren<{ + value: CasesContextProps; + queryClient?: QueryClient; + }> +> = ({ children, value: { externalReferenceAttachmentTypeRegistry, diff --git a/x-pack/plugins/cases/public/components/connectors/test_utils.tsx b/x-pack/plugins/cases/public/components/connectors/test_utils.tsx index 6b126ce995768..fca62d4e4f377 100644 --- a/x-pack/plugins/cases/public/components/connectors/test_utils.tsx +++ b/x-pack/plugins/cases/public/components/connectors/test_utils.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { Form, useForm } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import { EuiButton } from '@elastic/eui'; @@ -13,7 +14,7 @@ interface MockFormWrapperComponentProps { fields?: Record; } -export const MockFormWrapperComponent: React.FC = ({ +export const MockFormWrapperComponent: FC> = ({ children, fields = {}, }) => { diff --git a/x-pack/plugins/cases/public/components/create/assignees.test.tsx b/x-pack/plugins/cases/public/components/create/assignees.test.tsx index 002cd2976f605..883352a230c8f 100644 --- a/x-pack/plugins/cases/public/components/create/assignees.test.tsx +++ b/x-pack/plugins/cases/public/components/create/assignees.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import userEvent from '@testing-library/user-event'; import type { AppMockRenderer } from '../../common/mock'; @@ -27,7 +28,7 @@ describe('Assignees', () => { let globalForm: FormHook; let appMockRender: AppMockRenderer; - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm(); globalForm = form; diff --git a/x-pack/plugins/cases/public/components/create/category.test.tsx b/x-pack/plugins/cases/public/components/create/category.test.tsx index ed36e464ab449..85d5072bccc58 100644 --- a/x-pack/plugins/cases/public/components/create/category.test.tsx +++ b/x-pack/plugins/cases/public/components/create/category.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; @@ -26,7 +27,7 @@ describe('Category', () => { let appMockRender: AppMockRenderer; const onSubmit = jest.fn(); - const FormComponent: React.FC = ({ children }) => { + const FormComponent: FC = ({ children }) => { const { form } = useForm({ onSubmit }); return ( diff --git a/x-pack/plugins/cases/public/components/create/connector.test.tsx b/x-pack/plugins/cases/public/components/create/connector.test.tsx index 7bc4bfbde6162..d77983c662524 100644 --- a/x-pack/plugins/cases/public/components/create/connector.test.tsx +++ b/x-pack/plugins/cases/public/components/create/connector.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { mount } from 'enzyme'; import { act, waitFor } from '@testing-library/react'; @@ -65,7 +66,7 @@ describe('Connector', () => { let appMockRender: AppMockRenderer; let globalForm: FormHook; - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm({ defaultValue: { connectorId: connectorsMock[0].id, fields: null }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx b/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx index 8e21319c31842..e43a958430e1b 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx @@ -7,6 +7,7 @@ import { alertComment } from '../../../containers/mock'; import { renderHook } from '@testing-library/react-hooks'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { CasesContext } from '../../cases_context'; import { CasesContextStoreActionsList } from '../../cases_context/cases_context_reducer'; @@ -22,7 +23,7 @@ const persistableStateAttachmentTypeRegistry = new PersistableStateAttachmentTyp describe('use cases add to new case flyout hook', () => { const dispatch = jest.fn(); - let wrapper: React.FC; + let wrapper: FC; beforeEach(() => { dispatch.mockReset(); wrapper = ({ children }) => { diff --git a/x-pack/plugins/cases/public/components/create/form.test.tsx b/x-pack/plugins/cases/public/components/create/form.test.tsx index 65e5a378f53a8..b5b3f7bf7b677 100644 --- a/x-pack/plugins/cases/public/components/create/form.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { mount } from 'enzyme'; import { act, render, within, fireEvent, waitFor } from '@testing-library/react'; @@ -56,10 +57,11 @@ describe('CreateCaseForm', () => { let globalForm: FormHook; const draftStorageKey = `cases.caseView.createCase.description.markdownEditor`; - const MockHookWrapperComponent: React.FC<{ testProviderProps?: unknown }> = ({ - children, - testProviderProps = {}, - }) => { + const MockHookWrapperComponent: FC< + PropsWithChildren<{ + testProviderProps?: unknown; + }> + > = ({ children, testProviderProps = {} }) => { const { form } = useForm({ defaultValue: initialCaseValue, options: { stripEmptyFields: false }, diff --git a/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx b/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx index aa5d80e82a34f..f94cf78420744 100644 --- a/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx +++ b/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; @@ -18,7 +19,7 @@ import { schema } from './schema'; describe('SyncAlertsToggle', () => { let globalForm: FormHook; - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm({ defaultValue: { syncAlerts: true }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/tags.test.tsx b/x-pack/plugins/cases/public/components/create/tags.test.tsx index 65e94e8cc204e..0329a3875fcff 100644 --- a/x-pack/plugins/cases/public/components/create/tags.test.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { waitFor, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; @@ -28,7 +29,7 @@ describe('Tags', () => { let globalForm: FormHook; let appMockRender: AppMockRenderer; - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm({ defaultValue: { tags: [] }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/title.test.tsx b/x-pack/plugins/cases/public/components/create/title.test.tsx index 793a868f8a1cb..e592654176ac9 100644 --- a/x-pack/plugins/cases/public/components/create/title.test.tsx +++ b/x-pack/plugins/cases/public/components/create/title.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { mount } from 'enzyme'; import { act } from '@testing-library/react'; @@ -18,7 +19,7 @@ import { schema } from './schema'; describe('Title', () => { let globalForm: FormHook; - const MockHookWrapperComponent: React.FC = ({ children }) => { + const MockHookWrapperComponent: FC = ({ children }) => { const { form } = useForm({ defaultValue: { title: 'My title' }, schema: { diff --git a/x-pack/plugins/cases/public/components/timeline_context/index.tsx b/x-pack/plugins/cases/public/components/timeline_context/index.tsx index 9187a4131053e..3b5e4949150c0 100644 --- a/x-pack/plugins/cases/public/components/timeline_context/index.tsx +++ b/x-pack/plugins/cases/public/components/timeline_context/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useState } from 'react'; import type { EuiMarkdownEditorUiPlugin, EuiMarkdownAstNodePosition } from '@elastic/eui'; import type { Plugin } from 'unified'; @@ -51,9 +52,11 @@ export const CasesTimelineIntegrationContext = React.createContext = +export const CasesTimelineIntegrationProvider: FC< + PropsWithChildren<{ + timelineIntegration?: CasesTimelineIntegration; + }> +> = // TODO: Fix this manually. Issue #123375 // eslint-disable-next-line react/display-name ({ children, timelineIntegration }) => { diff --git a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx index 1ac198321210d..12f7afb64be14 100644 --- a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import { basicCase } from '../../containers/mock'; @@ -28,7 +29,7 @@ const patchComment = jest.fn(); const clearDraftComment = jest.fn(); const openLensModal = jest.fn(); -const wrapper: React.FC = ({ children }) => {children}; +const wrapper: FC = ({ children }) => {children}; describe('useUserActionsHandler', () => { beforeAll(() => { diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx index 6b1dda42d8fe1..c21890c098dc8 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx +++ b/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx @@ -5,8 +5,11 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; export const ActionWrapper = jest .fn() - .mockImplementation(({ children }) =>
{children}
); + .mockImplementation(({ children }: PropsWithChildren) => ( +
{children}
+ )); diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx index 1e1eb398c991b..6fb3d24c68836 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx +++ b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx @@ -13,6 +13,7 @@ import ReactDOM, { unmountComponentAtNode } from 'react-dom'; import { createAddToExistingCaseLensAction } from './add_to_existing_case'; import type { ActionContext } from './types'; import { useCasesAddToExistingCaseModal } from '../../all_cases/selector_modal/use_cases_add_to_existing_case_modal'; +import type { PropsWithChildren } from 'react'; import React from 'react'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { @@ -44,7 +45,9 @@ jest.mock('../../../client/helpers/can_use_cases', () => { }); jest.mock('@kbn/kibana-react-plugin/public', () => ({ - KibanaThemeProvider: jest.fn().mockImplementation(({ children }) => <>{children}), + KibanaThemeProvider: jest + .fn() + .mockImplementation(({ children }: PropsWithChildren) => <>{children}), })); jest.mock('@kbn/react-kibana-mount', () => ({ diff --git a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx index 2b5082a9e22a5..1329413685c4c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx @@ -9,6 +9,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { useGetCase } from './use_get_case'; import * as api from './api'; import { waitFor } from '@testing-library/react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useToasts } from '../common/lib/kibana'; @@ -16,7 +17,7 @@ import { useToasts } from '../common/lib/kibana'; jest.mock('./api'); jest.mock('../common/lib/kibana'); -const wrapper: React.FC = ({ children }) => { +const wrapper: FC = ({ children }) => { const queryClient = new QueryClient({ defaultOptions: { queries: { diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx index 44cec799c9f51..b0a2ca904af31 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import type { SingleCaseMetricsFeature } from '../../common/ui'; @@ -18,7 +19,7 @@ import { CaseMetricsFeature } from '../../common/types/api'; jest.mock('./api'); jest.mock('../common/lib/kibana'); -const wrapper: React.FC = ({ children }) => {children}; +const wrapper: FC = ({ children }) => {children}; describe('useGetCaseMetrics', () => { const abortCtrl = new AbortController(); diff --git a/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx b/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx index 66c3fc2c932eb..23f080bcee04b 100644 --- a/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx +++ b/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx @@ -4,9 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; -export const mockCasesContext: React.FC = (props) => { +export const mockCasesContext: FC = (props) => { return <>{props?.children ?? null}; }; mockCasesContext.displayName = 'CasesContextMock'; diff --git a/x-pack/plugins/cases/public/types.ts b/x-pack/plugins/cases/public/types.ts index 7e3d5293e3674..bb8790a299d12 100644 --- a/x-pack/plugins/cases/public/types.ts +++ b/x-pack/plugins/cases/public/types.ts @@ -7,7 +7,7 @@ import type { CoreStart } from '@kbn/core/public'; import type { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; -import type { ReactElement } from 'react'; +import type { ReactElement, PropsWithChildren } from 'react'; import type React from 'react'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public'; @@ -134,7 +134,7 @@ export interface CasesPublicStart { * @return {ReactElement} */ getCases: (props: GetCasesProps) => ReactElement; - getCasesContext: () => React.FC; + getCasesContext: () => React.FC>; /** * Modal to select a case in a list of all owner cases diff --git a/x-pack/plugins/cloud/public/mocks.tsx b/x-pack/plugins/cloud/public/mocks.tsx index 39257763b9b1c..cd95bd783545e 100644 --- a/x-pack/plugins/cloud/public/mocks.tsx +++ b/x-pack/plugins/cloud/public/mocks.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { CloudSetup, CloudStart } from './types'; @@ -35,7 +35,7 @@ function createSetupMock(): jest.Mocked { }; } -const getContextProvider: () => React.FC = +const getContextProvider: () => FC = () => ({ children }) => <>{children}; diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index 760436bfd4f6c..a210274b86252 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { Logger } from '@kbn/logging'; import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context'; @@ -56,7 +56,7 @@ export class CloudPlugin implements Plugin { private readonly config: CloudConfigType; private readonly isCloudEnabled: boolean; private readonly isServerlessEnabled: boolean; - private readonly contextProviders: FC[] = []; + private readonly contextProviders: Array> = []; private readonly logger: Logger; constructor(private readonly initializerContext: PluginInitializerContext) { @@ -112,7 +112,7 @@ export class CloudPlugin implements Plugin { // Nest all the registered context providers under the Cloud Services Provider. // This way, plugins only need to require Cloud's context provider to have all the enriched Cloud services. - const CloudContextProvider: FC = ({ children }) => { + const CloudContextProvider: FC = ({ children }) => { return ( <> {this.contextProviders.reduce( diff --git a/x-pack/plugins/cloud/public/types.ts b/x-pack/plugins/cloud/public/types.ts index a3d448668d8aa..b154c065e5b20 100644 --- a/x-pack/plugins/cloud/public/types.ts +++ b/x-pack/plugins/cloud/public/types.ts @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; export interface CloudStart { /** * A React component that provides a pre-wired `React.Context` which connects components to Cloud services. */ - CloudContextProvider: FC<{}>; + CloudContextProvider: FC; /** * `true` when Kibana is running on Elastic Cloud. */ diff --git a/x-pack/plugins/cloud_defend/public/components/loading_state/index.tsx b/x-pack/plugins/cloud_defend/public/components/loading_state/index.tsx index 608eabf0e30a8..9512df9285154 100644 --- a/x-pack/plugins/cloud_defend/public/components/loading_state/index.tsx +++ b/x-pack/plugins/cloud_defend/public/components/loading_state/index.tsx @@ -6,14 +6,15 @@ */ import { EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { FullSizeCenteredPage } from '../full_size_page'; // Keep this component lean as it is part of the main app bundle -export const LoadingState: React.FunctionComponent<{ ['data-test-subj']?: string }> = ({ - children, - ...rest -}) => { +export const LoadingState: FC< + PropsWithChildren<{ + ['data-test-subj']?: string; + }> +> = ({ children, ...rest }) => { return ( diff --git a/x-pack/plugins/cloud_defend/public/test/test_provider.tsx b/x-pack/plugins/cloud_defend/public/test/test_provider.tsx index e599e4063ac7c..cfd74d118ebe5 100755 --- a/x-pack/plugins/cloud_defend/public/test/test_provider.tsx +++ b/x-pack/plugins/cloud_defend/public/test/test_provider.tsx @@ -6,7 +6,7 @@ */ import type { AppMountParameters, CoreStart } from '@kbn/core/public'; -import React, { useMemo } from 'react'; +import React, { useMemo, FC, PropsWithChildren } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; @@ -41,7 +41,7 @@ interface CloudDefendAppDeps { params: AppMountParameters; } -export const TestProvider: React.FC> = ({ +export const TestProvider: FC>> = ({ core = coreMock.createStart(), deps = { data: dataPluginMock.createStartContract(), diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx index b9cf8a11da068..f6d66f09e23a0 100644 --- a/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { DecoratorFn } from '@storybook/react'; import { ServicesProvider, CloudChatServices } from '../public/services'; @@ -27,7 +27,7 @@ const services: CloudChatServices = { }, }; -export const getCloudContextProvider: () => React.FC = +export const getCloudContextProvider: () => FC = () => ({ children }) => {children}; diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx index 0abacc07dcfd8..b9a3f7e8420be 100644 --- a/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; export function whenIdle(doWork: () => void) { const requestIdleCallback = window.requestIdleCallback || window.setTimeout; @@ -21,7 +21,7 @@ export function whenIdle(doWork: () => void) { /** * Postpone rendering of children until the page is loaded and browser is idle. */ -export const WhenIdle: React.FC = ({ children }) => { +export const WhenIdle: FC = ({ children }) => { const [idleFired, setIdleFired] = React.useState(false); React.useEffect(() => { diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx index 7f6471f1229cb..20d0be66c3a7c 100755 --- a/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import useObservable from 'react-use/lib/useObservable'; import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; @@ -58,7 +58,7 @@ export class CloudChatPlugin implements Plugin { + const CloudChatContextProvider: FC = ({ children }) => { // There's a risk that the request for chat config will take too much time to complete, and the provider // will maintain a stale value. To avoid this, we'll use an Observable. const chatConfig = useObservable(this.chatConfig$, undefined); diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/public/services/index.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/public/services/index.tsx index c20d57a0e96f0..79aaf6f627299 100644 --- a/x-pack/plugins/cloud_integrations/cloud_chat/public/services/index.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/public/services/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, createContext, useContext } from 'react'; +import React, { FC, createContext, useContext, PropsWithChildren } from 'react'; import type { ChatVariant } from '../../common/types'; export interface ChatConfig { @@ -27,9 +27,10 @@ export interface CloudChatServices { const ServicesContext = createContext({}); -export const ServicesProvider: FC = ({ children, ...services }) => ( - {children} -); +export const ServicesProvider: FC> = ({ + children, + ...services +}) => {children}; /** * React hook for accessing the pre-wired `CloudChatServices`. diff --git a/x-pack/plugins/cloud_security_posture/public/components/chart_panel.tsx b/x-pack/plugins/cloud_security_posture/public/components/chart_panel.tsx index 6c813c480ed8c..2a8913bd9d948 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/chart_panel.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/chart_panel.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { ReactNode } from 'react'; +import React, { ReactNode, FC, PropsWithChildren } from 'react'; import { EuiPanel, EuiText, @@ -24,6 +24,7 @@ interface ChartPanelProps { isError?: boolean; rightSideItems?: ReactNode[]; styles?: React.CSSProperties; + children: React.ReactNode; } const Loading = () => ( @@ -48,7 +49,7 @@ const Error = () => ( ); -export const ChartPanel: React.FC = ({ +export const ChartPanel: FC> = ({ title, hasBorder = true, isLoading, diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx index ea9b276339f6a..37ddb8f3b5e9d 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiButtonEmpty, EuiFlexItem } from '@elastic/eui'; import { type DataView } from '@kbn/data-views-plugin/common'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -13,7 +13,7 @@ import { useStyles } from './use_styles'; import { getAbbreviatedNumber } from '../../common/utils/get_abbreviated_number'; import { CSP_FIELDS_SELECTOR_OPEN_BUTTON } from '../test_subjects'; -const GroupSelectorWrapper: React.FC = ({ children }) => { +const GroupSelectorWrapper: FC = ({ children }) => { const styles = useStyles(); return ( diff --git a/x-pack/plugins/cloud_security_posture/public/components/csp_loading_state.tsx b/x-pack/plugins/cloud_security_posture/public/components/csp_loading_state.tsx index 2c2e14c6f2dc7..a9704b519f06a 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/csp_loading_state.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/csp_loading_state.tsx @@ -6,14 +6,15 @@ */ import { EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { FullSizeCenteredPage } from './full_size_centered_page'; // Keep this component lean as it is part of the main app bundle -export const CspLoadingState: React.FunctionComponent<{ ['data-test-subj']?: string }> = ({ - children, - ...rest -}) => { +export const CspLoadingState: FC< + PropsWithChildren<{ + ['data-test-subj']?: string; + }> +> = ({ children, ...rest }) => { return ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index 421c53726371f..89b82b17d3187 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { RulesContainer } from './rules_container'; import { render, screen } from '@testing-library/react'; import { QueryClient } from '@tanstack/react-query'; @@ -36,7 +36,7 @@ const queryClient = new QueryClient({ }); const getWrapper = - ({ canUpdate = true }: { canUpdate: boolean } = { canUpdate: true }): React.FC => + ({ canUpdate = true }: { canUpdate: boolean } = { canUpdate: true }): FC => ({ children }) => { const coreStart = coreMock.createStart(); const core = { diff --git a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx index a2c71bc5e926a..d677df4258837 100755 --- a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx +++ b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx @@ -28,6 +28,7 @@ interface CspAppDeps { core: CoreStart; deps: Partial; params: AppMountParameters; + children: React.ReactNode; } export const TestProvider: React.FC> = ({ diff --git a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts index a458c69ee2650..aced694ff4172 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts @@ -5,6 +5,6 @@ * 2.0. */ -import { FunctionComponent } from 'react'; +import { FC, PropsWithChildren } from 'react'; -declare const AutoFollowPatternDeleteProvider: FunctionComponent; +declare const AutoFollowPatternDeleteProvider: FC; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx index 3b97aa6474e74..6988fcecd29d6 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx @@ -5,7 +5,7 @@ * 2.0. */ import '../_index.scss'; -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; @@ -39,7 +39,7 @@ export const FileDataVisualizer: FC = ({ getAdditionalLinks, resultLinks fieldFormats, }; - const EmptyContext: FC = ({ children }) => <>{children}; + const EmptyContext: FC = ({ children }) => <>{children}; const CloudContext = cloud?.CloudContextProvider || EmptyContext; return ( diff --git a/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx b/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx index 9ff0166a523ff..62b8d4a535235 100644 --- a/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx +++ b/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { Suspense } from 'react'; import { EuiErrorBoundary, EuiSkeletonText } from '@elastic/eui'; import type { ResultLinks } from '../../common/app'; import type { DataDriftDetectionAppStateProps } from '../application/data_drift/data_drift_app_state'; -const LazyWrapper: FC = ({ children }) => ( +const LazyWrapper: FC = ({ children }) => ( }>{children} diff --git a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/ai_search_guide/ai_search_guide_accordion.tsx b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/ai_search_guide/ai_search_guide_accordion.tsx index 80f8fcd7eb2c2..835d0d9b4770e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/ai_search_guide/ai_search_guide_accordion.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/ai_search_guide/ai_search_guide_accordion.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiAccordion, @@ -28,7 +28,7 @@ export interface AISearchGuideAccordionProps { currentExpandedId: string | undefined; } -export const AISearchGuideAccordion: React.FC = ({ +export const AISearchGuideAccordion: FC> = ({ id, icon, title, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx index d36ac9c2ced4a..a88c7f24b6281 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useEffect } from 'react'; +import React, { useEffect, FC, PropsWithChildren } from 'react'; import { useParams } from 'react-router-dom'; import { useValues, useActions } from 'kea'; @@ -28,7 +28,7 @@ interface Props { isQueryView?: boolean; isAnalyticsView?: boolean; } -export const AnalyticsLayout: React.FC = ({ +export const AnalyticsLayout: FC> = ({ title, breadcrumbs = [], isQueryView, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.tsx index 4be1cfb5ef9f3..68ab40e9b17b8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, @@ -23,7 +23,12 @@ interface Props { subtitle: string; title: string; } -export const AnalyticsSection: React.FC = ({ title, subtitle, iconType, children }) => ( +export const AnalyticsSection: FC> = ({ + title, + subtitle, + iconType, + children, +}) => (
{ ); }; -export const ApiLogHeading: React.FC = ({ children }) => ( +export const ApiLogHeading: FC = ({ children }) => (

{children}

diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.tsx index 83a0c8057a268..887231178d39c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiAccordion, EuiIcon } from '@elastic/eui'; @@ -22,7 +22,7 @@ interface SummarySectionAccordionProps { status: 'success' | 'error' | 'info'; title: string; } -export const SummarySectionAccordion: React.FC = ({ +export const SummarySectionAccordion: FC> = ({ id, status, title, diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx index 52647335d0f50..bfb67ec07bac5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -export const EmptySearchApplicationsPrompt: React.FC = ({ children }) => { +export const EmptySearchApplicationsPrompt: FC = ({ children }) => { return ( = ({ title, description, children }) => { +export const SchedulePanel: FC> = ({ + title, + description, + children, +}) => { return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/connector_sync_form.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/connector_sync_form.tsx index f7f226d5e266f..3357db856527e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/connector_sync_form.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/connector_sync_form.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useActions, useValues } from 'kea'; @@ -17,7 +17,7 @@ import { UnsavedChangesPrompt } from '../../../../../shared/unsaved_changes_prom import { ConnectorFilteringLogic } from './connector_filtering_logic'; -export const ConnectorSyncRulesForm: React.FC = ({ children }) => { +export const ConnectorSyncRulesForm: FC = ({ children }) => { const { saveDraftFilteringRules, setIsEditing } = useActions(ConnectorFilteringLogic); const { hasJsonValidationError, isEditing, isLoading } = useValues(ConnectorFilteringLogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/edit_sync_rules_tab.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/edit_sync_rules_tab.tsx index 3cb77ba2a3be4..a3d63db7c2c02 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/edit_sync_rules_tab.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/sync_rules/edit_sync_rules_tab.tsx @@ -5,17 +5,18 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ConnectorSyncRulesForm } from './connector_sync_form'; -export const EditSyncRulesTab: React.FC<{ revertAction: () => void }> = ({ - children, - revertAction, -}) => { +export const EditSyncRulesTab: FC< + PropsWithChildren<{ + revertAction: () => void; + }> +> = ({ children, revertAction }) => { return ( <> @@ -24,6 +25,7 @@ export const EditSyncRulesTab: React.FC<{ revertAction: () => void }> = ({ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx index 244f7a3e8a200..90f59d32a2787 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useValues } from 'kea'; @@ -38,7 +38,7 @@ export const InferenceConfiguration: React.FC = () => { } }; -const InferenceConfigurationWrapper: React.FC = ({ children }) => { +const InferenceConfigurationWrapper: FC = ({ children }) => { return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index 3bf568b428c73..c6763a6c97ad7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; @@ -92,7 +92,7 @@ export const renderApp = ( const productAccess = access || noProductAccess; const productFeatures = features ?? { ...DEFAULT_PRODUCT_FEATURES }; - const EmptyContext: FC = ({ children }) => <>{children}; + const EmptyContext: FC = ({ children }) => <>{children}; const CloudContext = cloud?.CloudContextProvider || EmptyContext; resetContext({ createStore: true }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx index f85eaa8dfe3c2..95afb29db1675 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { Fragment } from 'react'; +import React, { Fragment, FC, PropsWithChildren } from 'react'; import { useValues } from 'kea'; @@ -14,7 +14,7 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FLASH_MESSAGE_TYPES } from './constants'; import { FlashMessagesLogic } from './flash_messages_logic'; -export const FlashMessages: React.FC = ({ children }) => { +export const FlashMessages: FC = ({ children }) => { const { messages } = useValues(FlashMessagesLogic); return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx index 35f1d28378c74..da2d5702850f9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import React from 'react'; - +import React, { FC, PropsWithChildren } from 'react'; import { useState, useEffect } from 'react'; import { css } from '@emotion/react'; @@ -40,7 +39,7 @@ import { KibanaLogic } from '../kibana'; import { EndpointIcon } from './endpoint_icon'; -export const EndpointsHeaderAction: React.FC = ({ children }) => { +export const EndpointsHeaderAction: FC = ({ children }) => { const [isPopoverOpen, setPopoverOpen] = useState(false); const { cloud, esConfig, navigateToUrl } = useValues(KibanaLogic); const { makeRequest } = useActions(FetchApiKeysAPILogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_layout/personal_dashboard_layout.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_layout/personal_dashboard_layout.tsx index 1b87f8fdce4b2..a833eff37fbc7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_layout/personal_dashboard_layout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/personal_dashboard_layout/personal_dashboard_layout.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useRouteMatch } from 'react-router-dom'; import { useValues } from 'kea'; @@ -36,7 +36,7 @@ interface LayoutProps { pageChrome?: BreadcrumbTrail; } -export const PersonalDashboardLayout: React.FC = ({ +export const PersonalDashboardLayout: FC> = ({ children, isLoading, pageChrome, diff --git a/x-pack/plugins/fleet/.storybook/context/index.tsx b/x-pack/plugins/fleet/.storybook/context/index.tsx index 608414af27887..3b2d23e59291a 100644 --- a/x-pack/plugins/fleet/.storybook/context/index.tsx +++ b/x-pack/plugins/fleet/.storybook/context/index.tsx @@ -49,10 +49,10 @@ import { getCustomBranding } from './custom_branding'; // mock later, (or, ideally, Fleet starts to use a service abstraction). // // Expect this to grow as components that are given Stories need access to mocked services. -export const StorybookContext: React.FC<{ storyContext?: Parameters[1] }> = ({ - storyContext, - children: storyChildren, -}) => { +export const StorybookContext: React.FC<{ + children: React.ReactNode; + storyContext?: Parameters[1]; +}> = ({ storyContext, children: storyChildren }) => { const basepath = ''; const browserHistory = createBrowserHistory(); const history = new CoreScopedHistory(browserHistory, basepath); diff --git a/x-pack/plugins/fleet/public/applications/fleet/app.tsx b/x-pack/plugins/fleet/public/applications/fleet/app.tsx index ad66789128875..35098941434e1 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/app.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/app.tsx @@ -68,7 +68,7 @@ const FEEDBACK_URL = 'https://ela.st/fleet-feedback'; const queryClient = new QueryClient(); -export const WithPermissionsAndSetup: React.FC = memo(({ children }) => { +export const WithPermissionsAndSetup = memo<{ children?: React.ReactNode }>(({ children }) => { useBreadcrumbs('base'); const core = useStartServices(); const { notifications } = core; @@ -175,6 +175,7 @@ export const FleetAppContext: React.FC<{ /** For testing purposes only */ routerHistory?: History; fleetStatus?: FleetStatusProviderProps; + children: React.ReactNode; }> = memo( ({ children, diff --git a/x-pack/plugins/fleet/public/applications/fleet/layouts/error.tsx b/x-pack/plugins/fleet/public/applications/fleet/layouts/error.tsx index 982a11eb3e09e..89e47f3641c95 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/layouts/error.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/layouts/error.tsx @@ -22,10 +22,10 @@ const Panel = styled(EuiPanel)` margin-left: auto; `; -export const ErrorLayout: React.FunctionComponent<{ isAddIntegrationsPath: boolean }> = ({ - isAddIntegrationsPath, - children, -}) => ( +export const ErrorLayout: React.FunctionComponent<{ + children: React.ReactNode; + isAddIntegrationsPath: boolean; +}> = ({ isAddIntegrationsPath, children }) => ( {isAddIntegrationsPath ? ( }>{children} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/add_first_integration_splash.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/add_first_integration_splash.tsx index f620e74c2be02..81fc4175887fe 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/add_first_integration_splash.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/add_first_integration_splash.tsx @@ -37,7 +37,7 @@ import { CreatePackagePolicyBottomBar } from '.'; const CentralTitle = styled('h1')` text-align: center; `; -const PaddedCentralTitle: React.FC = ({ children }) => ( +const PaddedCentralTitle: React.FC<{ children?: React.ReactNode }> = ({ children }) => ( <> @@ -64,7 +64,7 @@ const CenteredEuiImage = (props: EuiImageProps) => (
); -const ResponsiveStepGroup: React.FC = ({ children }) => { +const ResponsiveStepGroup: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const isScreenSmall = useIsWithinMaxBreakpoint('s'); return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/page_steps/add_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/page_steps/add_integration.tsx index c858dae118269..3cad3d74b4d70 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/page_steps/add_integration.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/page_steps/add_integration.tsx @@ -30,7 +30,7 @@ import { NotObscuredByBottomBar } from '..'; import { StepConfigurePackagePolicy, StepDefinePackagePolicy } from '../../../components'; import { prepareInputPackagePolicyDataset } from '../../../services/prepare_input_pkg_policy_dataset'; -const ExpandableAdvancedSettings: React.FC = ({ children }) => { +const ExpandableAdvancedSettings: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const [isShowingAdvanced, setIsShowingAdvanced] = useState(false); return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/layout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/layout.tsx index 5eb4c55e53d45..e90a99841682d 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/layout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/layout.tsx @@ -45,6 +45,7 @@ export const CreatePackagePolicySinglePageLayout: React.FunctionComponent<{ isSelected: boolean; onClick: React.ReactEventHandler; }>; + children: React.ReactNode; }> = memo( ({ from, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration.tsx index 6c6ea2ca1173d..db14401edfadb 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration.tsx @@ -63,6 +63,7 @@ const StyledEuiAccordion = styled(EuiAccordion)` `; const CollapsablePanel: React.FC<{ + children: React.ReactNode; id: string; title: React.ReactNode; 'data-test-subj'?: string; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_status_filter.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_status_filter.tsx index dc32a18daf69e..be9098f2e7916 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_status_filter.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_status_filter.tsx @@ -67,6 +67,7 @@ const LeftpaddedNotificationBadge = styled(EuiNotificationBadge)` `; const InactiveAgentsTourStep: React.FC<{ + children: React.ReactNode; isOpen: boolean; setInactiveAgentsCalloutHasBeenDismissed: (val: boolean) => void; }> = ({ children, isOpen, setInactiveAgentsCalloutHasBeenDismissed }) => ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx index 68f0205a40c7c..969f9357a21db 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/es_requirements_page.tsx @@ -28,10 +28,10 @@ import { WithoutHeaderLayout } from '../../../layouts'; import type { GetFleetStatusResponse } from '../../../types'; import { useStartServices } from '../../../hooks'; -export const RequirementItem: React.FunctionComponent<{ isMissing: boolean }> = ({ - isMissing, - children, -}) => { +export const RequirementItem: React.FunctionComponent<{ + children: React.ReactNode; + isMissing: boolean; +}> = ({ isMissing, children }) => { return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/error_pages/components/no_data_layout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/error_pages/components/no_data_layout.tsx index c37bce702e978..ea6c92229fdf3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/error_pages/components/no_data_layout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/error_pages/components/no_data_layout.tsx @@ -10,6 +10,7 @@ import React from 'react'; import { withRouter } from 'react-router-dom'; interface LayoutProps { + children: React.ReactNode; title: string | React.ReactNode; actionSection?: React.ReactNode; } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx index a3b3b5f9bbf7d..695047288e298 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx @@ -62,7 +62,9 @@ export function withConfirmModalProvider(WrappedComponent: React.FunctionComp ); } -export const ConfirmModalProvider: React.FunctionComponent = ({ children }) => { +export const ConfirmModalProvider: React.FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const [isVisible, setIsVisible] = useState(false); const [modal, setModal] = useState({ onCancel: () => {}, diff --git a/x-pack/plugins/fleet/public/applications/integrations/app.tsx b/x-pack/plugins/fleet/public/applications/integrations/app.tsx index 5fba3d9886070..b7272481c015e 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/app.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/app.tsx @@ -63,6 +63,7 @@ export const IntegrationsAppContext: React.FC<{ /** For testing purposes only */ routerHistory?: History; // TODO remove fleetStatus?: FleetStatusProviderProps; + children: React.ReactNode; }> = memo( ({ children, diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx index 8b0671f0a9a45..c64b290d6f6df 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx @@ -13,6 +13,7 @@ import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal' import { toMountPoint } from '@kbn/kibana-react-plugin/public'; export interface Props { + children: React.ReactNode; setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; theme$: AppMountParameters['theme$']; } diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_agent_policy_context.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_agent_policy_context.tsx index 859db79ad159b..0ce254208918f 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_agent_policy_context.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_agent_policy_context.tsx @@ -17,7 +17,9 @@ interface AgentPolicyContextValue { const AgentPolicyContext = createContext({ getId: () => undefined }); -export const AgentPolicyContextProvider: FunctionComponent = ({ children }) => { +export const AgentPolicyContextProvider: FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const maybeState = useIntraAppState(); const ref = useRef(maybeState?.forAgentPolicyId); diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_integrations_state.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_integrations_state.tsx index e2b4a3ba1fa1b..9e4241a6e7f72 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_integrations_state.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_integrations_state.tsx @@ -19,7 +19,9 @@ const IntegrationsStateContext = createContext({ getFromIntegrations: () => undefined, }); -export const IntegrationsStateContextProvider: FunctionComponent = ({ children }) => { +export const IntegrationsStateContextProvider: FunctionComponent<{ + children?: React.ReactNode; +}> = ({ children }) => { const maybeState = useIntraAppState(); const fromIntegrationsRef = useRef(maybeState?.fromIntegrations); diff --git a/x-pack/plugins/fleet/public/applications/integrations/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/index.tsx index 7ec58031cf4ea..8dfef726157ba 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/index.tsx @@ -74,7 +74,7 @@ export function renderApp( config: FleetConfigType, kibanaVersion: string, extensions: UIExtensionsStorage, - UsageTracker: React.FC + UsageTracker: React.FC<{ children: React.ReactNode }> ) { ReactDOM.render( diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/grid.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/grid.tsx index 21cdf57c0d50f..0c495b2610f7f 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/grid.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/grid.tsx @@ -28,6 +28,7 @@ const VirtualizedRow: React.FC<{ index: number; onHeightChange: (index: number, size: number) => void; style: any; + children: React.ReactNode; }> = ({ index, children, style, onHeightChange }) => { const ref = useRef(null); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/requirements.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/requirements.tsx index af85f08ff5ea1..e028f45aaf7c8 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/requirements.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/requirements.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiDescriptionList, EuiToolTip } from '@elastic/eui'; -export const Requirements: React.FC = memo(() => { +export const Requirements = memo(() => { return ( diff --git a/x-pack/plugins/fleet/public/components/extension_wrapper.tsx b/x-pack/plugins/fleet/public/components/extension_wrapper.tsx index 9c7ebc03899e7..94029bbd88a43 100644 --- a/x-pack/plugins/fleet/public/components/extension_wrapper.tsx +++ b/x-pack/plugins/fleet/public/components/extension_wrapper.tsx @@ -11,10 +11,12 @@ import { EuiErrorBoundary } from '@elastic/eui'; import { Loading } from './loading'; -export const ExtensionWrapper = memo<{ children: ReactNode }>(({ children }) => { - return ( - - }>{children} - - ); -}); +export const ExtensionWrapper = memo<{ children: ReactNode }>( + ({ children }: { children?: React.ReactNode }) => { + return ( + + }>{children} + + ); + } +); diff --git a/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx b/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx index 1081522bb87b2..d10afc4d1806a 100644 --- a/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx +++ b/x-pack/plugins/fleet/public/hooks/use_fleet_status.tsx @@ -35,6 +35,7 @@ interface FleetStatus extends FleetStatusProviderProps { const FleetStatusContext = React.createContext(undefined); export const FleetStatusProvider: React.FC<{ + children: React.ReactNode; defaultFleetStatus?: FleetStatusProviderProps; }> = ({ defaultFleetStatus, children }) => { const config = useConfig(); diff --git a/x-pack/plugins/fleet/public/hooks/use_flyout_context.tsx b/x-pack/plugins/fleet/public/hooks/use_flyout_context.tsx index 3bec5db51aeb6..fc02493271108 100644 --- a/x-pack/plugins/fleet/public/hooks/use_flyout_context.tsx +++ b/x-pack/plugins/fleet/public/hooks/use_flyout_context.tsx @@ -19,7 +19,9 @@ const agentFlyoutContext = createContext< | undefined >(undefined); -export const FlyoutContextProvider: React.FunctionComponent = ({ children }) => { +export const FlyoutContextProvider: React.FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); const [isFleetServerFlyoutOpen, setIsFleetServerFlyoutOpen] = useState(false); diff --git a/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx b/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx index 4b331962d8eaa..2a122aff23db2 100644 --- a/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx +++ b/x-pack/plugins/fleet/public/mock/create_test_renderer.tsx @@ -72,7 +72,7 @@ export const createFleetTestRendererMock = (): TestRenderer => { ExperimentalFeaturesService.init(allowedExperimentalValues); - const HookWrapper = memo(({ children }) => { + const HookWrapper = memo(({ children }: { children?: React.ReactNode }) => { return ( @@ -94,7 +94,7 @@ export const createFleetTestRendererMock = (): TestRenderer => { startInterface: createStartMock(extensions), kibanaVersion: '8.0.0', setHeaderActionMenu: jest.fn(), - AppWrapper: memo(({ children }) => { + AppWrapper: memo(({ children }: { children?: React.ReactNode }) => { return ( { const basePath = '/mock'; const extensions: UIExtensionsStorage = {}; const startServices = createStartServices(basePath); - const HookWrapper = memo(({ children }) => { + const HookWrapper = memo(({ children }: { children?: React.ReactNode }) => { return ( {children} @@ -157,7 +157,7 @@ export const createIntegrationsTestRendererMock = (): TestRenderer => { startInterface: createStartMock(extensions), kibanaVersion: '8.0.0', setHeaderActionMenu: jest.fn(), - AppWrapper: memo(({ children }) => { + AppWrapper: memo(({ children }: { children?: React.ReactNode }) => { return ( ( +const TagListWrapper: FC<{ children?: React.ReactNode }> = ({ children }) => (
    = ({ children, topLevelSettings, phase }) => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/components/form.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/components/form.tsx index 5d1add85bf9f4..5aaee6f064ae8 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/components/form.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/components/form.tsx @@ -16,6 +16,7 @@ import { GlobalFieldsProvider } from '../global_fields_context'; interface Props { form: FormHook; + children: React.ReactNode; } export const Form: FunctionComponent = ({ form, children }) => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_context.tsx index 63dfaeed57e9f..76463a627f990 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_context.tsx @@ -48,7 +48,9 @@ const pathToHotPhaseSearchableSnapshot = const pathToColdPhaseSearchableSnapshot = 'phases.cold.actions.searchable_snapshot.snapshot_repository'; -export const ConfigurationProvider: FunctionComponent = ({ children }) => { +export const ConfigurationProvider: FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const [formData] = useFormData({ watch: [ pathToHotPhaseSearchableSnapshot, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/form_errors_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/form_errors_context.tsx index dfe7858eb3c7d..10fff1123d252 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/form_errors_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/form_errors_context.tsx @@ -53,7 +53,9 @@ const createEmptyErrors = (): Errors => ({ other: {}, }); -export const FormErrorsProvider: FunctionComponent = ({ children }) => { +export const FormErrorsProvider: FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const [errors, setErrors] = useState(createEmptyErrors); const form = useFormContext(); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/global_fields_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/global_fields_context.tsx index bb02e5a50a48a..61baaa5dc811c 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/global_fields_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/global_fields_context.tsx @@ -56,7 +56,9 @@ export const globalFields: Record { +export const GlobalFieldsProvider: FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { return ( fields={globalFields}> {(fields) => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/phase_timings_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/phase_timings_context.tsx index 12078f9c3f549..4364f03e2c5c5 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/phase_timings_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/phase_timings_context.tsx @@ -47,7 +47,9 @@ export interface PhaseTimings { const PhaseTimingsContext = createContext(null as any); -export const PhaseTimingsProvider: FunctionComponent = ({ children }) => { +export const PhaseTimingsProvider: FunctionComponent<{ children?: React.ReactNode }> = ({ + children, +}) => { const { deleteEnabled } = useGlobalFields(); const [formData] = useFormData({ watch: [ diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx index ac344bbeccb77..88da23007a4f6 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx @@ -10,11 +10,9 @@ import React from 'react'; import { AuthorizationProvider } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; -export const ComponentTemplatesAuthProvider: React.FunctionComponent = ({ - children, -}: { +export const ComponentTemplatesAuthProvider: React.FunctionComponent<{ children?: React.ReactNode; -}) => { +}> = ({ children }) => { const { httpClient, apiBasePath } = useComponentTemplatesContext(); return ( diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx index cc52e5a6d720d..5ae9b2f14ec82 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx @@ -17,11 +17,9 @@ import { } from '../shared_imports'; import { APP_CLUSTER_REQUIRED_PRIVILEGES } from '../constants'; -export const ComponentTemplatesWithPrivileges: FunctionComponent = ({ - children, -}: { +export const ComponentTemplatesWithPrivileges: FunctionComponent<{ children?: React.ReactNode; -}) => { +}> = ({ children }) => { const { apiError } = useAuthorizationContext(); if (apiError) { diff --git a/x-pack/plugins/index_management/public/application/components/enrich_policies/auth_provider.tsx b/x-pack/plugins/index_management/public/application/components/enrich_policies/auth_provider.tsx index 95feac22ffa9b..344cb308459d2 100644 --- a/x-pack/plugins/index_management/public/application/components/enrich_policies/auth_provider.tsx +++ b/x-pack/plugins/index_management/public/application/components/enrich_policies/auth_provider.tsx @@ -11,11 +11,9 @@ import { AuthorizationProvider } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; import { INTERNAL_API_BASE_PATH } from '../../../../common'; -export const EnrichPoliciesAuthProvider: React.FunctionComponent = ({ - children, -}: { +export const EnrichPoliciesAuthProvider: React.FunctionComponent<{ children?: React.ReactNode; -}) => { +}> = ({ children }) => { const { services: { httpService: { httpClient }, diff --git a/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx b/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx index 42101e495e291..09a79343b2210 100644 --- a/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx +++ b/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx @@ -17,11 +17,9 @@ import { } from '../../../shared_imports'; import { ENRICH_POLICIES_REQUIRED_PRIVILEGES } from '../../constants'; -export const EnrichPoliciesWithPrivileges: FunctionComponent = ({ - children, -}: { +export const EnrichPoliciesWithPrivileges: FunctionComponent<{ children?: React.ReactNode; -}) => { +}> = ({ children }) => { const { apiError } = useAuthorizationContext(); if (apiError) { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx index c9aaffd813c9b..3fe5f0ef40595 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx @@ -52,10 +52,10 @@ export interface Props { kibanaVersion: SemVer; } -// The default FormWrapper is the , which wrapps the form with +// The default FormWrapper is the , which wraps the form with // a
    . We can't have a div as first child of the Flyout as it breaks -// the height calculaction and does not render the footer position correctly. -const FormWrapper: React.FC = ({ children }) => <>{children}; +// the height calculation and does not render the footer position correctly. +const FormWrapper: React.FC<{ children?: React.ReactNode }> = ({ children }) => <>{children}; export const EditField = React.memo( ({ form, field, allFields, exitEdit, updateField, kibanaVersion }: Props) => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor_context.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor_context.tsx index 7a6e6947ff002..390d326c4f23f 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor_context.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor_context.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { StateProvider } from './mappings_state_context'; import { ConfigProvider } from './config_context'; -export const MappingsEditorProvider: React.FC = ({ children }) => { +export const MappingsEditorProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => { return ( {children} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state_context.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state_context.tsx index e2c213aec3078..ac41436f26c9d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state_context.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state_context.tsx @@ -13,7 +13,7 @@ import { State, Dispatch } from './types'; const StateContext = createContext(undefined); const DispatchContext = createContext(undefined); -export const StateProvider: React.FC = ({ children }) => { +export const StateProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const initialState: State = { isValid: true, configuration: { diff --git a/x-pack/plugins/index_management/public/application/index.tsx b/x-pack/plugins/index_management/public/application/index.tsx index 8c815a02907f8..43dd90e5bc1e8 100644 --- a/x-pack/plugins/index_management/public/application/index.tsx +++ b/x-pack/plugins/index_management/public/application/index.tsx @@ -29,6 +29,7 @@ const { GlobalFlyoutProvider } = GlobalFlyout; export interface IndexManagementAppContextProps { core: CoreStart; + children: React.ReactNode; dependencies: AppDependencies; } diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx index f6848a7f2bf45..2da59a371ec03 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx @@ -59,6 +59,7 @@ export interface Props { */ onFlyoutOpen: () => void; onUpdate: (arg: OnUpdateHandlerArg) => void; + children?: React.ReactNode; } export const PipelineProcessorsContextProvider: FunctionComponent = ({ diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 8a9f5e5d04605..374d651c44d8f 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { Observable, Subject } from 'rxjs'; import { ReactWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; @@ -107,9 +107,7 @@ describe('Lens App', () => { services?: jest.Mocked; preloadedState?: Partial; }) { - const wrappingComponent: React.FC<{ - children: React.ReactNode; - }> = ({ children }) => { + const wrappingComponent: React.FC> = ({ children }) => { return ( {children} diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index f5741dbfebe97..07e1627f6d066 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, useCallback, useEffect, useState, useMemo } from 'react'; +import React, { FC, PropsWithChildren, useCallback, useEffect, useState, useMemo } from 'react'; import { AppMountParameters, CoreSetup, CoreStart } from '@kbn/core/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { RouteComponentProps } from 'react-router-dom'; @@ -147,7 +147,7 @@ export async function mountApp( mountProps: { createEditorFrame: EditorFrameStart['createInstance']; attributeService: LensAttributeService; - getPresentationUtilContext: () => FC; + getPresentationUtilContext: () => FC>; topNavMenuEntryGenerators: LensTopNavMenuEntryGenerator[]; locator?: LensAppLocator; } diff --git a/x-pack/plugins/lens/public/mocks/store_mocks.tsx b/x-pack/plugins/lens/public/mocks/store_mocks.tsx index ad028bfe107f0..354b6cbac53c5 100644 --- a/x-pack/plugins/lens/public/mocks/store_mocks.tsx +++ b/x-pack/plugins/lens/public/mocks/store_mocks.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { ReactElement } from 'react'; +import React, { PropsWithChildren, ReactElement } from 'react'; import { ReactWrapper } from 'enzyme'; import { mountWithIntl as mount } from '@kbn/test-jest-helpers'; import { Provider } from 'react-redux'; @@ -80,9 +80,7 @@ export const renderWithReduxStore = ( const CustomWrapper = wrapper as React.ComponentType; - const Wrapper: React.FC<{ - children: React.ReactNode; - }> = ({ children }) => { + const Wrapper: React.FC> = ({ children }) => { return ( @@ -135,9 +133,7 @@ export const mountWithProvider = async ( component: React.ReactElement, store?: MountStoreProps, options?: { - wrappingComponent?: React.FC<{ - children: React.ReactNode; - }>; + wrappingComponent?: React.FC>; wrappingComponentProps?: Record; attachTo?: HTMLElement; } @@ -156,18 +152,16 @@ const getMountWithProviderParams = ( component: React.ReactElement, store?: MountStoreProps, options?: { - wrappingComponent?: React.FC<{ - children: React.ReactNode; - }>; + wrappingComponent?: React.FC>; wrappingComponentProps?: Record; attachTo?: HTMLElement; } ) => { const { store: lensStore, deps } = makeLensStore(store || {}); - let wrappingComponent: React.FC<{ - children: React.ReactNode; - }> = ({ children }) => {children}; + let wrappingComponent: React.FC> = ({ children }) => ( + {children} + ); let restOptions: { attachTo?: HTMLElement | undefined; diff --git a/x-pack/plugins/lens/public/shared_components/toolbar_popover.tsx b/x-pack/plugins/lens/public/shared_components/toolbar_popover.tsx index f2abfd971463b..acb6b36bed3e6 100644 --- a/x-pack/plugins/lens/public/shared_components/toolbar_popover.tsx +++ b/x-pack/plugins/lens/public/shared_components/toolbar_popover.tsx @@ -6,7 +6,7 @@ */ import './toolbar_popover.scss'; -import React, { useState } from 'react'; +import React, { PropsWithChildren, useState } from 'react'; import { EuiFlexItem, EuiPopover, EuiPopoverProps, EuiPopoverTitle, IconType } from '@elastic/eui'; import { ToolbarButton, ToolbarButtonProps } from '@kbn/shared-ux-button-toolbar'; import { EuiIconLegend } from '@kbn/chart-icons'; @@ -41,7 +41,7 @@ export type ToolbarPopoverProps = Partial & { handleClose?: () => void; }; -export const ToolbarPopover: React.FunctionComponent = ({ +export const ToolbarPopover: React.FC> = ({ children, title, type, diff --git a/x-pack/plugins/lists/public/lists/mocks/query_wrapper.tsx b/x-pack/plugins/lists/public/lists/mocks/query_wrapper.tsx index 605e998fe678f..f1034d034f78c 100644 --- a/x-pack/plugins/lists/public/lists/mocks/query_wrapper.tsx +++ b/x-pack/plugins/lists/public/lists/mocks/query_wrapper.tsx @@ -10,7 +10,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; export const createQueryWrapperMock = (): { queryClient: QueryClient; - wrapper: React.FC; + wrapper: React.FC<{ children: React.ReactNode }>; } => { const queryClient = new QueryClient({ defaultOptions: { diff --git a/x-pack/plugins/maps/public/render_app.tsx b/x-pack/plugins/maps/public/render_app.tsx index 6ca0258af9d20..4fe95154747e3 100644 --- a/x-pack/plugins/maps/public/render_app.tsx +++ b/x-pack/plugins/maps/public/render_app.tsx @@ -69,7 +69,7 @@ export async function renderApp( }: { coreStart: CoreStart; savedObjectsTagging?: SavedObjectTaggingPluginStart; - AppUsageTracker: React.FC; + AppUsageTracker: React.FC<{ children: React.ReactNode }>; } ) { const stateTransfer = getEmbeddableService().getStateTransfer(); diff --git a/x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx b/x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx index 48f28bf895e19..cd2ac05f14778 100644 --- a/x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx +++ b/x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx @@ -11,6 +11,7 @@ import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { useKibanaContextForPluginProvider } from '../hooks/use_kibana'; export interface CoreProvidersProps { + children?: React.ReactNode; core: CoreStart; theme$: AppMountParameters['theme$']; } diff --git a/x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx index 4d1feb4617dcf..b813cfa563a0f 100644 --- a/x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx +++ b/x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx @@ -28,10 +28,10 @@ export const useGlobalStorybookTheme = ({ globals: { euiTheme } }: StoryContext) }; }; -export const GlobalStorybookThemeProviders: React.FC<{ storyContext: StoryContext }> = ({ - children, - storyContext, -}) => { +export const GlobalStorybookThemeProviders: React.FC<{ + children: React.ReactNode; + storyContext: StoryContext; +}> = ({ children, storyContext }) => { const { theme, theme$ } = useGlobalStorybookTheme(storyContext); return ( diff --git a/x-pack/plugins/ml/common/types/storage.test.tsx b/x-pack/plugins/ml/common/types/storage.test.tsx index bbecb23addff3..a1473b23c5dcd 100644 --- a/x-pack/plugins/ml/common/types/storage.test.tsx +++ b/x-pack/plugins/ml/common/types/storage.test.tsx @@ -31,7 +31,7 @@ const mockStorage: Storage = { clear: jest.fn(), }; -const Provider: FC = ({ children }) => { +const Provider: FC<{ children?: React.ReactNode }> = ({ children }) => { return ( {children} diff --git a/x-pack/plugins/ml/public/application/components/collapsible_panel/collapsible_panel.tsx b/x-pack/plugins/ml/public/application/components/collapsible_panel/collapsible_panel.tsx index dbb04ddbc39f0..72b965e6ab5e1 100644 --- a/x-pack/plugins/ml/public/application/components/collapsible_panel/collapsible_panel.tsx +++ b/x-pack/plugins/ml/public/application/components/collapsible_panel/collapsible_panel.tsx @@ -21,7 +21,7 @@ import { useCurrentThemeVars } from '../../contexts/kibana'; export interface CollapsiblePanelProps { isOpen: boolean; onToggle: (isOpen: boolean) => void; - + children: React.ReactNode; header: React.ReactElement; headerItems?: React.ReactElement[]; } diff --git a/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx b/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx index 02c1a2c70aa92..3d1121e3ccb57 100644 --- a/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx +++ b/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx @@ -22,6 +22,7 @@ import { MLFieldStatsFlyoutContext } from './use_field_stats_flytout_context'; import { PopulatedFieldsCacheManager } from './populated_fields/populated_fields_cache_manager'; export const FieldStatsFlyoutProvider: FC<{ + children: React.ReactNode; dataView: DataView; fieldStatsServices: FieldStatsServices; timeRangeMs?: TimeRangeMs; diff --git a/x-pack/plugins/ml/public/application/components/help_popover/help_popover.tsx b/x-pack/plugins/ml/public/application/components/help_popover/help_popover.tsx index bbdb39f18bea2..7a3178b05e40b 100644 --- a/x-pack/plugins/ml/public/application/components/help_popover/help_popover.tsx +++ b/x-pack/plugins/ml/public/application/components/help_popover/help_popover.tsx @@ -27,6 +27,7 @@ export const HelpPopoverButton: FC<{ onClick: EuiLinkButtonProps['onClick'] }> = }; interface HelpPopoverProps { + children: React.ReactNode; anchorPosition?: EuiPopoverProps['anchorPosition']; title?: string; } diff --git a/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx b/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx index 65495fef13318..d1b43e6037a19 100644 --- a/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx +++ b/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useContext, useEffect } from 'react'; import { InPortal, OutPortal } from 'react-reverse-portal'; import { EuiSkeletonText } from '@elastic/eui'; @@ -14,7 +14,7 @@ import { MlPageControlsContext } from '../ml_page/ml_page'; /** * Component for setting the page header content. */ -export const MlPageHeader: FC = ({ children }) => { +export const MlPageHeader: FC = ({ children }) => { const { headerPortal, setIsHeaderMounted } = useContext(MlPageControlsContext); useEffect(() => { diff --git a/x-pack/plugins/ml/public/application/contexts/ml/data_source_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/data_source_context.tsx index 76954ab9e8488..b87b26ace3955 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/data_source_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/data_source_context.tsx @@ -34,7 +34,7 @@ export const DataSourceContext = React.createContext( * @param children * @constructor */ -export const DataSourceContextProvider: FC = ({ children }) => { +export const DataSourceContextProvider: FC<{ children?: React.ReactNode }> = ({ children }) => { const [value, setValue] = useState(); const [error, setError] = useState(); diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx index 161cdf66e6a44..79c1e8d535c99 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx @@ -39,7 +39,9 @@ export const MlNotificationsContext = React.createContext<{ setLastCheckedAt: () => {}, }); -export const MlNotificationsContextProvider: FC = ({ children }) => { +export const MlNotificationsContextProvider: FC<{ children?: React.ReactNode }> = ({ + children, +}) => { const { services: { mlServices: { mlApiServices }, diff --git a/x-pack/plugins/ml/public/application/contexts/ml/serverless_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/serverless_context.tsx index 0fd5d8aee3c23..8bba7b67cc4da 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/serverless_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/serverless_context.tsx @@ -28,6 +28,7 @@ export const EnabledFeaturesContext = createContext({ }); interface Props { + children: React.ReactNode; isServerless: boolean; mlFeatures: MlFeatures; showMLNavMenu?: boolean; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/description.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/description.tsx index d2e1a063125ae..3b6ac4c7eb656 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/description.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/description.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -13,7 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui'; import { css } from '@emotion/react'; import { useMlKibana } from '../../../../../contexts/kibana'; -export const Description: FC = memo(({ children }) => { +export const Description: FC> = memo(({ children }) => { const { services: { docLinks }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/explorer/alerts/swim_lane_wrapper.tsx b/x-pack/plugins/ml/public/application/explorer/alerts/swim_lane_wrapper.tsx index d5a0b67f63939..ab18827ad6bf6 100644 --- a/x-pack/plugins/ml/public/application/explorer/alerts/swim_lane_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/explorer/alerts/swim_lane_wrapper.tsx @@ -49,6 +49,7 @@ import { statusNameMap } from './const'; import { Y_AXIS_LABEL_WIDTH } from '../constants'; export interface SwimLaneWrapperProps { + children: React.ReactNode; selection?: AppStateSelectedCells | null; swimlaneContainerWidth?: number; swimLaneData: SwimlaneData; diff --git a/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx b/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx index 4228881a5e4fe..b3b1fcc97f7a9 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx @@ -52,7 +52,9 @@ export function useAnomalyExplorerContext() { /** * Anomaly Explorer Context Provider. */ -export const AnomalyExplorerContextProvider: FC = ({ children }) => { +export const AnomalyExplorerContextProvider: FC<{ children?: React.ReactNode }> = ({ + children, +}) => { const [, , anomalyExplorerUrlStateService] = useExplorerUrlState(); const timefilter = useTimefilter(); diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.tsx b/x-pack/plugins/ml/public/application/explorer/explorer.tsx index c88711b0279f3..47cd51812e452 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer.tsx @@ -102,6 +102,7 @@ interface ExplorerPageProps { queryString?: string; updateLanguage?: (language: string) => void; dataViews?: DataView[]; + children: React.ReactNode; } const ExplorerPage: FC = ({ diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/charts/loading_wrapper/loading_wrapper.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/charts/loading_wrapper/loading_wrapper.tsx index fc9a79409b659..5fa952da73569 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/charts/loading_wrapper/loading_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/charts/loading_wrapper/loading_wrapper.tsx @@ -13,6 +13,7 @@ interface Props { hasData: boolean; height?: string; loading?: boolean; + children?: React.ReactNode; } export const LoadingWrapper: FC = ({ hasData, loading = false, height, children }) => { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/model_memory_limit/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/model_memory_limit/description.tsx index 9bd1a02d08c20..592f0bbc2efd9 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/model_memory_limit/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/model_memory_limit/description.tsx @@ -13,6 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/description.tsx index f648b451ec488..248adaa34ae97 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate('xpack.ml.newJob.wizard.datafeedStep.dataView.title', { defaultMessage: 'Data view', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/frequency/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/frequency/description.tsx index 2770f4097559b..3a43d1a10bbc0 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/frequency/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/frequency/description.tsx @@ -13,6 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query/description.tsx index 9dbe46f2f6594..78d04584d71c5 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query/description.tsx @@ -5,12 +5,11 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate('xpack.ml.newJob.wizard.datafeedStep.query.title', { defaultMessage: 'Elasticsearch query', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query_delay/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query_delay/description.tsx index 3a0410634ea43..05929fae8e760 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query_delay/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/query_delay/description.tsx @@ -13,6 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/scroll_size/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/scroll_size/description.tsx index 60b35cb468082..a6bb58607f4e7 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/scroll_size/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/scroll_size/description.tsx @@ -13,6 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/time_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/time_field/description.tsx index 44b41001fdbee..1f6c8570ae214 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/time_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/time_field/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate('xpack.ml.newJob.wizard.datafeedStep.timeField.title', { defaultMessage: 'Time field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx index 4d32a17f0484e..08282ea8f52da 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx @@ -5,14 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui'; import { useMlKibana } from '../../../../../../../../../contexts/kibana'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const { services: { docLinks }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/custom_urls/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/custom_urls/description.tsx index 66088fa31b51e..42eebff43e055 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/custom_urls/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/custom_urls/description.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -13,7 +12,7 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui'; import { css } from '@emotion/react'; import { useMlKibana } from '../../../../../../../../../contexts/kibana'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const { services: { docLinks }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/annotations/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/annotations/description.tsx index d7ecc537cdeaa..9f278d698be36 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/annotations/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/annotations/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlotAnnotations.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/dedicated_index/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/dedicated_index/description.tsx index 1e096a4d70f66..a6ab79de38681 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/dedicated_index/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/dedicated_index/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.useDedicatedIndex.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/ignore_unavailable/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/ignore_unavailable/description.tsx index 9fa5c388f9b27..5bfcdcdbbc368 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/ignore_unavailable/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/ignore_unavailable/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiCode, EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.ignoreUnavailable.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/model_plot/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/model_plot/description.tsx index 589af51b43a4f..6bfec5f628dfe 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/model_plot/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/advanced_section/components/model_plot/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlot.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/groups/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/groups/description.tsx index 6bd8c9c449f61..b070a68d7ebd4 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/groups/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/groups/description.tsx @@ -13,6 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_description/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_description/description.tsx index 2e846d641e4a7..876d811980062 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_description/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_description/description.tsx @@ -5,13 +5,12 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }: { children?: React.ReactNode }) => { const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobDescription.title', { defaultMessage: 'Job description', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_id/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_id/description.tsx index d5422c5d35387..4a5ef4166ed1e 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_id/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/job_id/description.tsx @@ -12,6 +12,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import type { Validation } from '../../../../../common/job_validator'; interface Props { + children: React.ReactNode; validation: Validation; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx index dfc1e17b97b1e..e543c862e8057 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -13,7 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiFlexGroup, EuiFlexItem } from '@e import { FunctionHelpPopover } from './function_help'; -export const AggDescription: FC = memo(({ children }) => { +export const AggDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.aggSelect.title', { @@ -46,7 +46,7 @@ export const AggDescription: FC = memo(({ children }) => { ); }); -export const FieldDescription: FC = memo(({ children }) => { +export const FieldDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.fieldSelect.title', { @@ -70,7 +70,7 @@ export const FieldDescription: FC = memo(({ children }) => { ); }); -export const ByFieldDescription: FC = memo(({ children }) => { +export const ByFieldDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.byFieldSelect.title', { @@ -94,7 +94,7 @@ export const ByFieldDescription: FC = memo(({ children }) => { ); }); -export const OverFieldDescription: FC = memo(({ children }) => { +export const OverFieldDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.overFieldSelect.title', { @@ -118,7 +118,7 @@ export const OverFieldDescription: FC = memo(({ children }) => { ); }); -export const PartitionFieldDescription: FC = memo(({ children }) => { +export const PartitionFieldDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.partitionFieldSelect.title', { @@ -142,7 +142,7 @@ export const PartitionFieldDescription: FC = memo(({ children }) => { ); }); -export const ExcludeFrequentDescription: FC = memo(({ children }) => { +export const ExcludeFrequentDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.excludeFrequent.title', { @@ -166,7 +166,7 @@ export const ExcludeFrequentDescription: FC = memo(({ children }) => { ); }); -export const DescriptionDescription: FC = memo(({ children }) => { +export const DescriptionDescription = memo(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.description.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/function_help.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/function_help.tsx index 41b9c24c635b3..a72380828a6db 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/function_help.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/function_help.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { useState, memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -20,7 +19,7 @@ import { } from '@elastic/eui'; import { useMlKibana } from '../../../../../../../contexts/kibana'; -export const FunctionHelpPopover: FC = memo(() => { +export const FunctionHelpPopover = memo(() => { const { services: { docLinks }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/modal_wrapper.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/modal_wrapper.tsx index 12050f2bafca6..e9e472a251bfe 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/modal_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/modal_wrapper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { @@ -26,7 +26,12 @@ interface Props { saveEnabled: boolean; } -export const ModalWrapper: FC = ({ onCreateClick, closeModal, saveEnabled, children }) => { +export const ModalWrapper: FC> = ({ + onCreateClick, + closeModal, + saveEnabled, + children, +}) => { return ( = memo(({ children, validation }) => { +export const Description: FC> = memo(({ children, validation }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.bucketSpan.title', { defaultMessage: 'Bucket span', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_field/description.tsx index a2e888aad2178..844cde946a258 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_field/description.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -14,7 +14,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; interface Props { isOptional: boolean; } -export const Description: FC = memo(({ children, isOptional }) => { +export const Description: FC> = memo(({ children, isOptional }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.categorizationField.title', { defaultMessage: 'Categorization field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx index 8a1123f32545c..681145a1f7de0 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -14,7 +14,7 @@ import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; interface Props { children: React.ReactNode; } -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.perPartitionCategorization.enable.title', { defaultMessage: 'Per-partition categorization', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx index 1cf72c4138ae9..7fc0189dc7c81 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiBasicTable, EuiCodeBlock } from '@elastic/eui'; @@ -73,6 +73,6 @@ export const FieldExamples: FC = ({ fieldExamples }) => { ); }; -const Token: FC = ({ children }) => ( +const Token: FC = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/detector_title/detector_title.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/detector_title/detector_title.tsx index 0cdc880b8907e..d153ee2bf2842 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/detector_title/detector_title.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/detector_title/detector_title.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -23,7 +23,7 @@ interface DetectorTitleProps { deleteDetector?: (dtrIds: number) => void; } -export const DetectorTitle: FC = ({ +export const DetectorTitle: FC> = ({ index, agg, field, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx index abfd8bedf74bf..8edca937c5042 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.geoField.title', { defaultMessage: 'Geo field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx index 82690313bb29c..5ff7b0a385174 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.influencers.title', { defaultMessage: 'Influencers', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx index 94aa67870c30d..f8c237696024b 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.populationField.title', { defaultMessage: 'Population field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx index f52783029b03d..58c269ae6e6e3 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.splitRareField.title', { defaultMessage: 'Rare field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx index 85ae7f0d3aec4..247dea4716b91 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.sparseData.title', { defaultMessage: 'Sparse data', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_cards/split_cards.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_cards/split_cards.tsx index 95aebe3c2952c..7966a73c85faa 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_cards/split_cards.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_cards/split_cards.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { memo, Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; @@ -26,7 +26,7 @@ interface Panel { marginBottom: number; } -export const SplitCards: FC = memo( +export const SplitCards: FC> = memo( ({ fieldValues, splitField, children, numberOfDetectors, jobType, animate = false }) => { const panels: Panel[] = []; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx index ebe692589d772..e8980258477eb 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description: FC = memo(({ children }) => { +export const Description = memo(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.splitField.title', { defaultMessage: 'Split field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/summary_count_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/summary_count_field/description.tsx index ace4ef32f0187..5dc177d0c1c90 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/summary_count_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/summary_count_field/description.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -17,7 +17,7 @@ interface Props { validation: Validation; } -export const Description: FC = memo(({ children, validation }) => { +export const Description: FC> = memo(({ children, validation }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.summaryCountField.title', { defaultMessage: 'Summary count field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx index c50bbfb97b10d..e8d46428a6401 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -50,4 +50,6 @@ export const DatafeedSectionTitle: FC = () => ( ); -export const Italic: FC = ({ children }) => {children}; +export const Italic: FC = ({ children }) => ( + {children} +); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/wizard_nav/wizard_nav.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/wizard_nav/wizard_nav.tsx index 0d449cddc89ff..0eb3ba6a6bacd 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/wizard_nav/wizard_nav.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/wizard_nav/wizard_nav.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -25,7 +25,7 @@ interface StepsNavProps { next?(): void; } -export const WizardNav: FC = ({ +export const WizardNav: FC> = ({ previous, previousActive = true, next, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx index 13a2d70b5ea8d..e81650e17c646 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { Fragment, useState, useMemo, useEffect, useContext } from 'react'; import { i18n } from '@kbn/i18n'; @@ -188,7 +188,10 @@ export const WizardSteps: FC = ({ currentStep, setCurrentStep }) => { ); }; -const Title: FC<{ 'data-test-subj': string }> = ({ 'data-test-subj': dataTestSubj, children }) => { +const Title: FC> = ({ + 'data-test-subj': dataTestSubj, + children, +}) => { return ( diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx index 91e6650a544f7..40ce2f2d2ffb5 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { render, waitFor } from '@testing-library/react'; import { DatePickerContextProvider, type DatePickerDependencies } from '@kbn/ml-date-picker'; @@ -57,7 +57,7 @@ const getMockedDatePickeDependencies = () => { } as unknown as DatePickerDependencies; }; -const Wrapper: FC = ({ children }) => ( +const Wrapper: FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/ml/public/application/routing/ml_page_wrapper.tsx b/x-pack/plugins/ml/public/application/routing/ml_page_wrapper.tsx index d9a446147873b..3833422f5b4aa 100644 --- a/x-pack/plugins/ml/public/application/routing/ml_page_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/routing/ml_page_wrapper.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; -export const MlPageWrapper: FC<{ path: string }> = ({ path, children }) => { +export const MlPageWrapper: FC> = ({ path, children }) => { return {children}; }; diff --git a/x-pack/plugins/ml/public/application/routing/router.tsx b/x-pack/plugins/ml/public/application/routing/router.tsx index 9170666d6affd..522d62d09b000 100644 --- a/x-pack/plugins/ml/public/application/routing/router.tsx +++ b/x-pack/plugins/ml/public/application/routing/router.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import type { RouteProps } from 'react-router-dom'; import { type Location } from 'history'; @@ -60,7 +60,10 @@ export interface PageDependencies { setBreadcrumbs: ChromeStart['setBreadcrumbs']; } -export const PageLoader: FC<{ context: RouteResolverContext }> = ({ context, children }) => { +export const PageLoader: FC> = ({ + context, + children, +}) => { const isLoading = !context.initialized; if (context?.resolvedComponent) { diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx index 77c1c1f108522..69e4285647bdb 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; import { render } from '@testing-library/react'; import { I18nProvider } from '@kbn/i18n-react'; @@ -24,7 +25,7 @@ jest.mock('../../../timeseriesexplorer', () => ({ })); jest.mock('../../../timeseriesexplorer/timeseriesexplorer_page', () => ({ - TimeSeriesExplorerPage: jest.fn(({ children }) => { + TimeSeriesExplorerPage: jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }), })); diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx index ee96494a77e09..84fbb702f121b 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { EuiSelectProps } from '@elastic/eui'; @@ -85,7 +85,7 @@ interface SeriesControlsProps { /** * Component for handling the detector and entities controls. */ -export const SeriesControls: FC = ({ +export const SeriesControls: FC> = ({ appStateHandler, bounds, children, diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_page.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_page.tsx index 87a90effffc87..08390b10858b6 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_page.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_page.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { i18n } from '@kbn/i18n'; @@ -26,7 +26,7 @@ interface TimeSeriesExplorerPageProps { noSingleMetricJobsFound?: boolean; } -export const TimeSeriesExplorerPage: FC = ({ +export const TimeSeriesExplorerPage: FC> = ({ children, dateFormatTz, resizeRef, diff --git a/x-pack/plugins/monitoring/public/application/contexts/global_state_context.tsx b/x-pack/plugins/monitoring/public/application/contexts/global_state_context.tsx index 7d5ab0be65033..44b1fd9f53995 100644 --- a/x-pack/plugins/monitoring/public/application/contexts/global_state_context.tsx +++ b/x-pack/plugins/monitoring/public/application/contexts/global_state_context.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { createContext, useState } from 'react'; +import React, { createContext, useState, FC, PropsWithChildren } from 'react'; import type { TimeRange } from '@kbn/es-query'; import { RefreshInterval } from '@kbn/data-plugin/public'; import useUnmount from 'react-use/lib/useUnmount'; @@ -36,7 +36,7 @@ const REFRESH_INTERVAL_OVERRIDE = { value: 10000, }; -export const GlobalStateProvider: React.FC = ({ +export const GlobalStateProvider: FC> = ({ uiSettings, query, toasts, 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 d1feae38a05ce..88868295b0bca 100644 --- a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx @@ -6,7 +6,7 @@ */ import { EuiPage, EuiPageBody, EuiPageTemplate, EuiTab, EuiTabs, EuiSpacer } from '@elastic/eui'; -import React, { useContext, useState, useEffect, useCallback } from 'react'; +import React, { useContext, useState, useEffect, useCallback, FC, PropsWithChildren } from 'react'; import { useHistory } from 'react-router-dom'; import type { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; import { HeaderMenuPortal } from '@kbn/observability-shared-plugin/public'; @@ -42,7 +42,7 @@ export interface PageTemplateProps { product?: string; } -export const PageTemplate: React.FC = ({ +export const PageTemplate: FC> = ({ title, pageTitle, tabs, diff --git a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx index 613d74726238a..f175ef877a660 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiLoadingChart } from '@elastic/eui'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -38,7 +38,7 @@ export const getDomain = (series: Array<{ name?: string; data: Coordinate[] }>) }; }; -const EmptyContainer: React.FC = ({ children }) => ( +const EmptyContainer: FC = ({ children }) => (
    = ({ - kibanaEnvironment = {}, - children, - }) => { + const Provider: FC< + PropsWithChildren<{ + kibanaEnvironment?: KibanaEnvContext; + }> + > = ({ kibanaEnvironment = {}, children }) => { const newProvider = createElement(KibanaEnvironmentContext.Provider, { value: { ...kibanaEnvironment, ...value }, children, diff --git a/x-pack/plugins/observability_solution/apm/public/hooks/use_breakpoints.test.tsx b/x-pack/plugins/observability_solution/apm/public/hooks/use_breakpoints.test.tsx index 7af7f258447ed..a7e3186dda8f4 100644 --- a/x-pack/plugins/observability_solution/apm/public/hooks/use_breakpoints.test.tsx +++ b/x-pack/plugins/observability_solution/apm/public/hooks/use_breakpoints.test.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { EuiProvider } from '@elastic/eui'; import { useBreakpoints } from './use_breakpoints'; -const wrapper: FC = ({ children }) => ( +const wrapper: FC = ({ children }) => ( { return { yMin: min || 0, yMax: max || 0, xMin: minTimestamp, xMax: maxTimestamp }; }; -export const EmptyContainer: React.FC = ({ children }) => ( +export const EmptyContainer: FC = ({ children }) => (
    (
    ); -export const ChartContainer: React.FC = ({ children }) => ( +export const ChartContainer: FC = ({ children }) => (
    = (props) => { +export const ExpressionRow: FC> = (props) => { const [isExpanded, toggle] = useToggle(true); const { children, setRuleParams, expression, errors, expressionId, remove, canDelete, fields } = diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index 475bb0b1fbdef..7af01adebb9c8 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -7,7 +7,7 @@ import { EuiButton, EuiCallOut, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState, FC, PropsWithChildren } from 'react'; import useMount from 'react-use/lib/useMount'; import { ForLastExpression, @@ -115,7 +115,7 @@ export const ExpressionEditor: React.FC< ); }; -export const SourceStatusWrapper: React.FC = ({ children }) => { +export const SourceStatusWrapper: FC = ({ children }) => { const { load, isLoading, hasFailedLoading, isUninitialized } = useLogViewContext(); return ( diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx index b26f057dd9853..d9cd347896e68 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx @@ -17,7 +17,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { omit } from 'lodash'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState, FC, PropsWithChildren } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { AggregationType, @@ -74,7 +74,7 @@ const StyledHealth = euiStyled(EuiHealth)` margin-left: 4px; `; -export const ExpressionRow: React.FC = (props) => { +export const ExpressionRow: FC> = (props) => { const [isExpanded, toggle] = useToggle(true); const { diff --git a/x-pack/plugins/observability_solution/infra/public/apps/common_providers.tsx b/x-pack/plugins/observability_solution/infra/public/apps/common_providers.tsx index 6370d83589ee1..4cd8847695fd5 100644 --- a/x-pack/plugins/observability_solution/infra/public/apps/common_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/apps/common_providers.tsx @@ -6,7 +6,7 @@ */ import { AppMountParameters, CoreStart } from '@kbn/core/public'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -23,13 +23,15 @@ import { HeaderActionMenuProvider } from '../utils/header_action_menu_provider'; import { TriggersActionsProvider } from '../utils/triggers_actions_context'; import { useIsDarkMode } from '../hooks/use_is_dark_mode'; -export const CommonInfraProviders: React.FC<{ - appName: string; - storage: Storage; - triggersActionsUI: TriggersAndActionsUIPublicPluginStart; - setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; - theme$: AppMountParameters['theme$']; -}> = ({ children, triggersActionsUI, setHeaderActionMenu, appName, storage, theme$ }) => { +export const CommonInfraProviders: FC< + PropsWithChildren<{ + appName: string; + storage: Storage; + triggersActionsUI: TriggersAndActionsUIPublicPluginStart; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; + theme$: AppMountParameters['theme$']; + }> +> = ({ children, triggersActionsUI, setHeaderActionMenu, appName, storage, theme$ }) => { const darkMode = useIsDarkMode(); return ( @@ -53,7 +55,7 @@ export interface CoreProvidersProps { kibanaEnvironment?: KibanaEnvContext; } -export const CoreProviders: React.FC = ({ +export const CoreProviders: FC> = ({ children, core, pluginStart, @@ -86,8 +88,11 @@ export const CoreProviders: React.FC = ({ ); }; -const DataUIProviders: React.FC<{ appName: string; storage: Storage }> = ({ - appName, - children, - storage, -}) => {children}; +const DataUIProviders: FC< + PropsWithChildren<{ + appName: string; + storage: Storage; + }> +> = ({ appName, children, storage }) => ( + {children} +); diff --git a/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx b/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx index fb5776c7ecc07..ddfc58bce784f 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx @@ -7,8 +7,7 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import { transparentize } from 'polished'; -import React from 'react'; - +import React, { FC, PropsWithChildren } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; export const LoadingOverlayWrapper: React.FC< @@ -25,7 +24,7 @@ export const LoadingOverlayWrapper: React.FC< ); }; -const Overlay: React.FC = ({ children }) => ( +const Overlay: FC = ({ children }) => ( {children ? children : } ); diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx index 57eb7e0105750..4a94825443212 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx @@ -6,14 +6,16 @@ */ import { EuiCallOut } from '@elastic/eui'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { RecreateJobButton } from '../log_analysis_setup/create_job_button'; -export const RecreateJobCallout: React.FC<{ - hasSetupCapabilities?: boolean; - onRecreateMlJob: () => void; - title?: React.ReactNode; -}> = ({ children, hasSetupCapabilities, onRecreateMlJob, title }) => ( +export const RecreateJobCallout: FC< + PropsWithChildren<{ + hasSetupCapabilities?: boolean; + onRecreateMlJob: () => void; + title?: React.ReactNode; + }> +> = ({ children, hasSetupCapabilities, onRecreateMlJob, title }) => ( {children} void; -}> = ({ children, onViewModuleList }) => ( +const LogAnalysisSetupFlyoutSubPage: FC< + PropsWithChildren<{ + children: React.ReactNode; + onViewModuleList?: () => void; + }> +> = ({ children, onViewModuleList }) => ( {onViewModuleList ? ( diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_entry_examples/log_entry_examples.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_entry_examples/log_entry_examples.tsx index ed2546d9b8d67..2acb77b9406b6 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_entry_examples/log_entry_examples.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_entry_examples/log_entry_examples.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import React from 'react'; - +import React, { FC, PropsWithChildren } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { LogEntryExampleMessagesEmptyIndicator } from './log_entry_examples_empty_indicator'; import { LogEntryExampleMessagesFailureIndicator } from './log_entry_examples_failure_indicator'; @@ -19,7 +18,7 @@ interface Props { exampleCount: number; onReload: () => void; } -export const LogEntryExampleMessages: React.FunctionComponent = ({ +export const LogEntryExampleMessages: FC> = ({ isLoading, hasFailedLoading, exampleCount, diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana.tsx b/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana.tsx index e62d6fbbc4e3c..5dde349e4de5b 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana.tsx +++ b/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana.tsx @@ -6,7 +6,14 @@ */ import type { PropsOf } from '@elastic/eui'; -import React, { useMemo, createElement, createContext, useContext } from 'react'; +import React, { + useMemo, + createElement, + createContext, + useContext, + FC, + PropsWithChildren, +} from 'react'; import { CoreStart } from '@kbn/core/public'; import { createKibanaReactContext, @@ -61,7 +68,10 @@ export const useKibanaEnvironmentContextProvider = (kibanaEnvironment?: KibanaEn [kibanaEnvironment] ); - const Provider: React.FC<{ kibanaEnv?: KibanaEnvContext }> = ({ kibanaEnv = {}, children }) => { + const Provider: FC> = ({ + kibanaEnv = {}, + children, + }) => { const newProvider = createElement(KibanaEnvironmentContext.Provider, { value: { ...kibanaEnv, ...value }, children, diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_index_patterns.mock.tsx b/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_index_patterns.mock.tsx index 1937e1ec7d6f9..5eb3cb0e13886 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_index_patterns.mock.tsx +++ b/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_index_patterns.mock.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useMemo, FC, PropsWithChildren } from 'react'; import { firstValueFrom, from, of } from 'rxjs'; import { delay } from 'rxjs'; import { CoreStart } from '@kbn/core/public'; @@ -23,10 +23,12 @@ export type MockIndexPatternSpec = Pick = ({ asyncDelay, children, mockIndexPatterns }) => { +export const MockIndexPatternsKibanaContextProvider: FC< + PropsWithChildren<{ + asyncDelay: number; + mockIndexPatterns: MockIndexPatternSpec[]; + }> +> = ({ asyncDelay, children, mockIndexPatterns }) => { const indexPatterns = useMemo( () => createIndexPatternsMock(asyncDelay, mockIndexPatterns.map(createIndexPatternMock)), [asyncDelay, mockIndexPatterns] diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 89bcd98d0958f..5cab07479a19b 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { logEntryCategoriesJobType } from '../../../../common/log_analysis'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; @@ -16,7 +16,7 @@ import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; import { useLogMlJobIdFormatsShimContext } from '../shared/use_log_ml_job_id_formats_shim'; -export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ children }) => { +export const LogEntryCategoriesPageProviders: FC = ({ children }) => { const { hasFailedLoading, isLoading, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 273874f83ae3e..1e31b28f87b0f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { logEntryCategoriesJobType, logEntryRateJobType } from '../../../../common/log_analysis'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; @@ -18,7 +18,7 @@ import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; import { useLogMlJobIdFormatsShimContext } from '../shared/use_log_ml_job_id_formats_shim'; -export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) => { +export const LogEntryRatePageProviders: FC = ({ children }) => { const { hasFailedLoading, isLoading, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx index f4112b7bd0a05..d2b745127862b 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useState, FC, PropsWithChildren } from 'react'; import { LogViewProvider, initializeFromUrl as createInitializeFromUrl, @@ -16,7 +16,7 @@ import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analy import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context'; -export const LogsPageProviders: React.FunctionComponent = ({ children }) => { +export const LogsPageProviders: FC = ({ children }) => { const { services: { notifications: { toasts: toastsService }, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_log_view_error.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_log_view_error.tsx index cb10d2785cbfd..2ecb9efb7003c 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_log_view_error.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_log_view_error.tsx @@ -7,7 +7,7 @@ import { EuiButton, EuiButtonEmpty, EuiCallOut, EuiEmptyPrompt, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useCallback } from 'react'; +import React, { useCallback, FC, PropsWithChildren } from 'react'; import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common'; import { useLinkProps } from '@kbn/observability-shared-plugin/public'; import { useSelector } from '@xstate/react'; @@ -161,7 +161,10 @@ const LogSourceErrorMessage: React.FC<{ error: Error }> = ({ error }) => { } }; -const LogSourceErrorCallout: React.FC<{ title: React.ReactNode }> = ({ title, children }) => ( +const LogSourceErrorCallout: FC> = ({ + title, + children, +}) => (

    {children}

    diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx index 9b058bd03acd3..a9415f331fef1 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx @@ -6,7 +6,7 @@ */ import stringify from 'json-stable-stringify'; -import React, { useMemo } from 'react'; +import React, { useMemo, FC, PropsWithChildren } from 'react'; import { LogHighlightsStateProvider, LogPositionStateProvider, @@ -24,7 +24,7 @@ import { LogViewConfigurationProvider } from '../../../containers/logs/log_view_ import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; -const ViewLogInContext: React.FC = ({ children }) => { +const ViewLogInContext: FC = ({ children }) => { const { startTimestamp, endTimestamp } = useLogPositionStateContext(); const { logViewReference } = useLogViewContext(); @@ -43,9 +43,11 @@ const ViewLogInContext: React.FC = ({ children }) => { ); }; -const LogEntriesStateProvider: React.FC<{ - logStreamPageState: InitializedLogStreamPageState; -}> = ({ children, logStreamPageState }) => { +const LogEntriesStateProvider: FC< + PropsWithChildren<{ + logStreamPageState: InitializedLogStreamPageState; + }> +> = ({ children, logStreamPageState }) => { const { logViewReference } = useLogViewContext(); const { startTimestamp, endTimestamp, targetPosition } = useLogPositionStateContext(); const { @@ -70,9 +72,11 @@ const LogEntriesStateProvider: React.FC<{ ); }; -const LogHighlightsState: React.FC<{ - logStreamPageState: InitializedLogStreamPageState; -}> = ({ children, logStreamPageState }) => { +const LogHighlightsState: FC< + PropsWithChildren<{ + logStreamPageState: InitializedLogStreamPageState; + }> +> = ({ children, logStreamPageState }) => { const { logViewReference, logView } = useLogViewContext(); const { topCursor, bottomCursor, entries } = useLogStreamContext(); const serializedParsedQuery = useMemo( @@ -92,10 +96,12 @@ const LogHighlightsState: React.FC<{ return {children}; }; -export const LogStreamPageContentProviders: React.FC<{ - logStreamPageState: InitializedLogStreamPageState; - logStreamPageCallbacks: LogStreamPageCallbacks; -}> = ({ children, logStreamPageState, logStreamPageCallbacks }) => { +export const LogStreamPageContentProviders: FC< + PropsWithChildren<{ + logStreamPageState: InitializedLogStreamPageState; + logStreamPageCallbacks: LogStreamPageCallbacks; + }> +> = ({ children, logStreamPageState, logStreamPageCallbacks }) => { return ( diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx index 9d4e36ded1524..3c1217889e28c 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx @@ -6,7 +6,7 @@ */ import { createMemoryHistory } from 'history'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { Router } from '@kbn/shared-ux-router'; import { mountHook } from '@kbn/test-jest-helpers'; import { CoreScopedHistory } from '@kbn/core/public'; @@ -70,7 +70,7 @@ const createProviderWrapper = () => { history.push(INITIAL_URL); const scopedHistory = new CoreScopedHistory(history, INITIAL_URL); - const ProviderWrapper: React.FC = ({ children }) => { + const ProviderWrapper: FC = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/types.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/types.ts index 2cf5c8844d726..4d5c5ad7ea861 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/types.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/types.ts @@ -6,6 +6,7 @@ */ import rt from 'io-ts'; +import { PropsWithChildren } from 'react'; import { EuiTheme } from '@kbn/kibana-react-plugin/common'; import { InventoryFormatterTypeRT } from '@kbn/metrics-data-access-plugin/common'; import { MetricsTimeInput } from './hooks/use_metrics_time'; @@ -18,7 +19,7 @@ export interface LayoutProps { stopLiveStreaming?: () => void; } -export type LayoutPropsWithTheme = LayoutProps & { theme: EuiTheme }; +export type LayoutPropsWithTheme = LayoutProps & PropsWithChildren<{ theme: EuiTheme }>; const ChartTypesRT = rt.keyof({ area: null, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx index bce24d25e0e25..f68868a556316 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useMetricsExplorerData } from './use_metrics_explorer_data'; @@ -36,7 +36,7 @@ const queryClient = new QueryClient({ }); const renderUseMetricsExplorerDataHook = () => { - const wrapper: React.FC = ({ children }) => { + const wrapper: FC = ({ children }) => { const services = { http: { post: mockedFetch, diff --git a/x-pack/plugins/observability_solution/infra/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/observability_solution/infra/public/test_utils/use_global_storybook_theme.tsx index 4d1feb4617dcf..a24fd9b549a05 100644 --- a/x-pack/plugins/observability_solution/infra/public/test_utils/use_global_storybook_theme.tsx +++ b/x-pack/plugins/observability_solution/infra/public/test_utils/use_global_storybook_theme.tsx @@ -6,7 +6,7 @@ */ import type { DecoratorFn } from '@storybook/react'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState, FC, PropsWithChildren } from 'react'; import { BehaviorSubject } from 'rxjs'; import type { CoreTheme } from '@kbn/core/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; @@ -28,10 +28,11 @@ export const useGlobalStorybookTheme = ({ globals: { euiTheme } }: StoryContext) }; }; -export const GlobalStorybookThemeProviders: React.FC<{ storyContext: StoryContext }> = ({ - children, - storyContext, -}) => { +export const GlobalStorybookThemeProviders: FC< + PropsWithChildren<{ + storyContext: StoryContext; + }> +> = ({ children, storyContext }) => { const { theme, theme$ } = useGlobalStorybookTheme(storyContext); return ( diff --git a/x-pack/plugins/observability_solution/infra/public/utils/header_action_menu_provider.tsx b/x-pack/plugins/observability_solution/infra/public/utils/header_action_menu_provider.tsx index 4e6381c9e6719..b5177bf3f5aba 100644 --- a/x-pack/plugins/observability_solution/infra/public/utils/header_action_menu_provider.tsx +++ b/x-pack/plugins/observability_solution/infra/public/utils/header_action_menu_provider.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { AppMountParameters } from '@kbn/core/public'; interface ContextProps { @@ -15,7 +15,7 @@ interface ContextProps { export const HeaderActionMenuContext = React.createContext({}); -export const HeaderActionMenuProvider: React.FC> = ({ +export const HeaderActionMenuProvider: React.FC>> = ({ setHeaderActionMenu, theme$, children, diff --git a/x-pack/plugins/observability_solution/infra/public/utils/triggers_actions_context.tsx b/x-pack/plugins/observability_solution/infra/public/utils/triggers_actions_context.tsx index ff8b4b89a19fd..4851d5ddb1aa0 100644 --- a/x-pack/plugins/observability_solution/infra/public/utils/triggers_actions_context.tsx +++ b/x-pack/plugins/observability_solution/infra/public/utils/triggers_actions_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; interface ContextProps { @@ -20,7 +20,7 @@ interface Props { triggersActionsUI: TriggersAndActionsUIPublicPluginStart; } -export const TriggersActionsProvider: React.FC = (props) => { +export const TriggersActionsProvider: FC> = (props) => { return ( = ({ - children, - resetOnChange = null, -}) => { +export const LogStreamErrorBoundary: FC< + PropsWithChildren<{ + resetOnChange: any; + }> +> = ({ children, resetOnChange = null }) => { return ( { return `/test-basepath/s/test-space/app/${app}${options?.path}`; }); -const ProviderWrapper: React.FC = ({ children }) => { +const ProviderWrapper: FC = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/column_headers.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/column_headers.tsx index a1b1cbf8fe770..88161e794c37e 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/column_headers.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/column_headers.tsx @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { @@ -102,10 +102,12 @@ export const LogColumnHeaders: React.FunctionComponent<{ ); }; -export const LogColumnHeader: React.FunctionComponent<{ - columnWidth: LogEntryColumnWidth; - 'data-test-subj'?: string; -}> = ({ children, columnWidth, 'data-test-subj': dataTestSubj }) => ( +export const LogColumnHeader: FC< + PropsWithChildren<{ + columnWidth: LogEntryColumnWidth; + 'data-test-subj'?: string; + }> +> = ({ children, columnWidth, 'data-test-subj': dataTestSubj }) => ( {children} diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx index 6d1dcd8322ec2..8f360c5c48618 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; /** * Create a separator with a text on the right side */ -export const LogTextSeparator: React.FC = ({ children }) => { +export const LogTextSeparator: FC = ({ children }) => { return ( {children} diff --git a/x-pack/plugins/observability_solution/logs_shared/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/observability_solution/logs_shared/public/test_utils/use_global_storybook_theme.tsx index 4d1feb4617dcf..a24fd9b549a05 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/test_utils/use_global_storybook_theme.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/test_utils/use_global_storybook_theme.tsx @@ -6,7 +6,7 @@ */ import type { DecoratorFn } from '@storybook/react'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState, FC, PropsWithChildren } from 'react'; import { BehaviorSubject } from 'rxjs'; import type { CoreTheme } from '@kbn/core/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; @@ -28,10 +28,11 @@ export const useGlobalStorybookTheme = ({ globals: { euiTheme } }: StoryContext) }; }; -export const GlobalStorybookThemeProviders: React.FC<{ storyContext: StoryContext }> = ({ - children, - storyContext, -}) => { +export const GlobalStorybookThemeProviders: FC< + PropsWithChildren<{ + storyContext: StoryContext; + }> +> = ({ children, storyContext }) => { const { theme, theme$ } = useGlobalStorybookTheme(storyContext); return ( diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/criterion_preview_chart/criterion_preview_chart.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/criterion_preview_chart/criterion_preview_chart.tsx index 806844e2531f6..7143104423d63 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/criterion_preview_chart/criterion_preview_chart.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/criterion_preview_chart/criterion_preview_chart.tsx @@ -86,7 +86,7 @@ export const getChartTheme = (isDarkMode: boolean): Theme => { return isDarkMode ? LEGACY_DARK_THEME : LEGACY_LIGHT_THEME; }; -export const EmptyContainer: React.FC = ({ children }) => ( +export const EmptyContainer: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
    (
    ); -export const ChartContainer: React.FC = ({ children }) => ( +export const ChartContainer: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
    { beforeEach(() => { jest.clearAllMocks(); - wrapper = ({ children }) => ( + wrapper = ({ children }: PropsWithChildren) => ( {children} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/certificates/monitor_page_link.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/certificates/monitor_page_link.tsx index 33bfed341606e..1e13cea7bb684 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/certificates/monitor_page_link.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/certificates/monitor_page_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiLink } from '@elastic/eui'; import { useKibana } from '@kbn/kibana-react-plugin/public'; @@ -13,7 +13,10 @@ interface DetailPageLinkProps { configId: string; } -export const MonitorPageLink: FC = ({ children, configId }) => { +export const MonitorPageLink: FC> = ({ + children, + configId, +}) => { const basePath = useKibana().services.http?.basePath.get(); return ( = ({ to, children }) => { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx index 32fa6cba8f5a1..6ecc80e587a7d 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton, EuiEmptyPrompt, EuiLoadingLogo } from '@elastic/eui'; import { useSyntheticsServiceAllowed } from '../../../hooks/use_service_allowed'; -export const ServiceAllowedWrapper: React.FC = ({ children }) => { +export const ServiceAllowedWrapper: FC = ({ children }) => { const { isAllowed, signupUrl, loading } = useSyntheticsServiceAllowed(); if (loading) { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx index f63cb3b7f6dc5..103e523935e64 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiForm, EuiSpacer } from '@elastic/eui'; import { FormProvider } from 'react-hook-form'; import { useFormWrapped } from '../../../../../hooks/use_form_wrapped'; @@ -14,12 +14,14 @@ import { getDefaultFormFields, formatDefaultFormValues } from './defaults'; import { ActionBar } from './submit'; import { Disclaimer } from './disclaimer'; -export const MonitorForm: React.FC<{ - defaultValues?: SyntheticsMonitor; - space?: string; - readOnly?: boolean; - canUsePublicLocations?: boolean; -}> = ({ children, defaultValues, space, readOnly = false, canUsePublicLocations }) => { +export const MonitorForm: FC< + PropsWithChildren<{ + defaultValues?: SyntheticsMonitor; + space?: string; + readOnly?: boolean; + canUsePublicLocations?: boolean; + }> +> = ({ children, defaultValues, space, readOnly = false, canUsePublicLocations }) => { const methods = useFormWrapped({ mode: 'onSubmit', reValidateMode: 'onSubmit', diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx index 20658b38c6c54..48d4410b47514 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useEffect, useState, useMemo, useRef } from 'react'; +import React, { useEffect, useState, useMemo, useRef, FC, PropsWithChildren } from 'react'; import { useHistory, useParams, useLocation } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; @@ -15,7 +15,7 @@ import { resetMonitorLastRunAction } from '../../state'; import { useMonitorLatestPing } from './hooks/use_monitor_latest_ping'; import { useSyntheticsRefreshContext } from '../../contexts'; -export const MonitorPendingWrapper: React.FC = ({ children }) => { +export const MonitorPendingWrapper: FC = ({ children }) => { const dispatch = useDispatch(); const history = useHistory(); const currentLocation = useLocation(); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx index 8ba0f20d4379a..e9069d6dfdf7c 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx @@ -6,7 +6,7 @@ */ import { EuiFocusTrap, EuiOverlayMask, EuiPanel, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui'; -import React, { useRef, useState } from 'react'; +import React, { useRef, useState, FC, PropsWithChildren } from 'react'; import { useSelector } from 'react-redux'; import { get, invert, orderBy } from 'lodash'; import styled from 'styled-components'; @@ -154,7 +154,10 @@ export const GridItemsByGroup = ({ ); }; -const WrappedPanel: React.FC<{ isFullScreen: boolean }> = ({ isFullScreen, children }) => { +const WrappedPanel: FC> = ({ + isFullScreen, + children, +}) => { const ref = useRef(null); if (!isFullScreen) { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_empty_state.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_empty_state.tsx index 9723447bc2c48..ff0ffea15bd36 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_empty_state.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_empty_state.tsx @@ -5,19 +5,21 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useSelector } from 'react-redux'; import { PrivateLocation } from '../../../../../../common/runtime_types'; import { AgentPolicyNeeded } from './agent_policy_needed'; import { EmptyLocations } from './empty_locations'; import { selectAgentPolicies } from '../../../state/private_locations'; -export const ManageEmptyState: FC<{ - privateLocations: PrivateLocation[]; - setIsAddingNew?: (val: boolean) => void; - showNeedAgentPolicy?: boolean; - showEmptyLocations?: boolean; -}> = ({ +export const ManageEmptyState: FC< + PropsWithChildren<{ + privateLocations: PrivateLocation[]; + setIsAddingNew?: (val: boolean) => void; + showNeedAgentPolicy?: boolean; + showEmptyLocations?: boolean; + }> +> = ({ children, privateLocations, setIsAddingNew, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/view_location_monitors.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/view_location_monitors.tsx index 6de55d6f424f6..4bcc226d37aac 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/view_location_monitors.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/view_location_monitors.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useMemo, useState } from 'react'; +import React, { useMemo, useState, FC, PropsWithChildren } from 'react'; import { EuiPopover, EuiButtonEmpty, EuiButton, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -62,7 +62,10 @@ export const ViewLocationMonitors = ({ ); }; -const ViewLocationMonitorsButton: React.FC<{ href: string }> = ({ href, children }) => { +const ViewLocationMonitorsButton: FC> = ({ + href, + children, +}) => { return ( {children} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/context/waterfall_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/context/waterfall_context.tsx index 7e5184ecf59f7..39b8479560cbb 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/context/waterfall_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/context/waterfall_context.tsx @@ -5,7 +5,14 @@ * 2.0. */ -import React, { createContext, useContext, Context, Dispatch, SetStateAction } from 'react'; +import React, { + createContext, + useContext, + Context, + Dispatch, + SetStateAction, + PropsWithChildren, +} from 'react'; import { JourneyStep } from '../../../../../../../../common/runtime_types'; import { WaterfallData, @@ -54,7 +61,7 @@ export interface IWaterfallContext { export const WaterfallContext = createContext>({}); -export const WaterfallProvider: React.FC = ({ +export const WaterfallProvider: React.FC> = ({ children, data, markerItems, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_data_view_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_data_view_context.tsx index 4e38a3de25388..b7a7c8f25602b 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_data_view_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_data_view_context.tsx @@ -5,16 +5,18 @@ * 2.0. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, FC, PropsWithChildren } from 'react'; import { useFetcher } from '@kbn/observability-shared-plugin/public'; import { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public'; import { SYNTHETICS_INDEX_PATTERN } from '../../../../common/constants'; export const SyntheticsDataViewContext = createContext({} as DataView); -export const SyntheticsDataViewContextProvider: React.FC<{ - dataViews: DataViewsPublicPluginStart; -}> = ({ children, dataViews }) => { +export const SyntheticsDataViewContextProvider: FC< + PropsWithChildren<{ + dataViews: DataViewsPublicPluginStart; + }> +> = ({ children, dataViews }) => { const { data } = useFetcher>(async () => { return dataViews.create({ title: SYNTHETICS_INDEX_PATTERN }); }, []); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx index 2628db4d93177..beddff01404e6 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx @@ -5,7 +5,16 @@ * 2.0. */ -import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import React, { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, + FC, + PropsWithChildren, +} from 'react'; import { useSelector } from 'react-redux'; import { useEvent } from 'react-use'; import moment from 'moment'; @@ -25,7 +34,7 @@ const defaultContext: SyntheticsRefreshContext = { export const SyntheticsRefreshContext = createContext(defaultContext); -export const SyntheticsRefreshContextProvider: React.FC = ({ children }) => { +export const SyntheticsRefreshContextProvider: FC = ({ children }) => { const [lastRefresh, setLastRefresh] = useState(Date.now()); const refreshPaused = useSelector(selectRefreshPaused); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx index 52b455dbc17c5..b221997efe9c3 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx @@ -12,7 +12,7 @@ import { CoreStart, I18nStart, } from '@kbn/core/public'; -import React, { createContext, useContext, useMemo } from 'react'; +import React, { createContext, useContext, useMemo, PropsWithChildren } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { ClientPluginsSetup, ClientPluginsStart } from '../../../plugin'; import { CLIENT_DEFAULTS, CONTEXT_DEFAULTS } from '../../../../common/constants'; @@ -78,7 +78,7 @@ const defaultContext: SyntheticsSettingsContextValues = { }; export const SyntheticsSettingsContext = createContext(defaultContext); -export const SyntheticsSettingsContextProvider: React.FC = ({ +export const SyntheticsSettingsContextProvider: React.FC> = ({ children, ...props }) => { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_startup_plugins_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_startup_plugins_context.tsx index 75ee7b3d6ae67..cfb28cbbff553 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_startup_plugins_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_startup_plugins_context.tsx @@ -5,14 +5,15 @@ * 2.0. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, PropsWithChildren } from 'react'; import { ClientPluginsStart } from '../../../plugin'; export const SyntheticsStartupPluginsContext = createContext>({}); -export const SyntheticsStartupPluginsContextProvider: React.FC> = ({ - children, - ...props -}) => ; +export const SyntheticsStartupPluginsContextProvider: React.FC< + PropsWithChildren> +> = ({ children, ...props }) => ( + +); export const useSyntheticsStartPlugins = () => useContext(SyntheticsStartupPluginsContext); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx index c2c19f815b90f..b57bdaa0cd365 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx @@ -6,7 +6,7 @@ */ import { euiLightVars, euiDarkVars } from '@kbn/ui-theme'; -import React, { createContext, useContext, useMemo } from 'react'; +import React, { createContext, useContext, useMemo, FC, PropsWithChildren } from 'react'; import { DARK_THEME, LIGHT_THEME, PartialTheme, Theme } from '@elastic/charts'; export interface SyntheticsAppColors { @@ -54,7 +54,7 @@ interface ThemeContextProps { darkMode: boolean; } -export const SyntheticsThemeContextProvider: React.FC = ({ +export const SyntheticsThemeContextProvider: FC> = ({ darkMode, children, }) => { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/helper_with_redux.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/helper_with_redux.tsx index 23831b1a4bc25..86f3075a9b854 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/helper_with_redux.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/helper_with_redux.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { Store } from 'redux'; import { createStore as createReduxStore, applyMiddleware } from 'redux'; @@ -23,11 +23,13 @@ const createRealStore = (): Store => { return store; }; -export const MountWithReduxProvider: React.FC<{ state?: AppState; useRealStore?: boolean }> = ({ - children, - state, - useRealStore, -}) => { +export const MountWithReduxProvider: FC< + PropsWithChildren<{ + state?: AppState; + children: React.ReactNode; + useRealStore?: boolean; + }> +> = ({ children, state, useRealStore }) => { const store = useRealStore ? createRealStore() : { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx index 827f8aa041801..d6a95eec921c5 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, HTMLAttributes } from 'react'; +import React, { FC, PropsWithChildren, HTMLAttributes } from 'react'; import { EuiErrorBoundary, EuiFlexGroup, EuiFlexItem, EuiLoadingChart } from '@elastic/eui'; interface Props { @@ -23,7 +23,7 @@ interface Props { 'aria-label'?: string; } -export const ChartWrapper: FC = ({ +export const ChartWrapper: FC> = ({ loading = false, height = '100%', children, diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_page_link.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_page_link.tsx index fe511cf93ced0..b2a3bb5522cc1 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_page_link.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_page_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ReactRouterEuiLink } from './react_router_helpers'; interface DetailPageLinkProps { @@ -19,7 +19,7 @@ interface DetailPageLinkProps { linkParameters: string | undefined; } -export const MonitorPageLink: FC = ({ +export const MonitorPageLink: FC> = ({ children, monitorId, linkParameters, diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx index ab79fe400221e..f353d85d96bf5 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx @@ -6,7 +6,7 @@ */ import { render, fireEvent, screen } from '@testing-library/react'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { MonitorTags } from './monitor_tags'; import * as hooks from '../../hooks/use_url_params'; @@ -165,7 +165,9 @@ describe('MonitorTags component', () => { it('expand tag show tags on click', () => { summaryPing.state.summaryPings[0].tags = ['red', 'green', 'blue', 'black', 'purple', 'yellow']; - const Wrapper: React.FC = ({ children }) => {children}; + const Wrapper: FC = ({ children }) => ( + {children} + ); render(, { wrapper: Wrapper }); fireEvent.click(screen.getByText('+1')); diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx index d0adab4944990..9378099ce4e85 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useHistory } from 'react-router-dom'; import { EuiLink, @@ -25,11 +25,11 @@ import { letBrowserHandleEvent } from './link_events'; * https://github.com/elastic/eui/blob/master/wiki/react-router.md#react-router-51 */ -interface IEuiReactRouterProps { +type IEuiReactRouterProps = PropsWithChildren<{ to: string; -} +}>; -export const ReactRouterHelperForEui: React.FC = ({ to, children }) => { +export const ReactRouterHelperForEui: FC = ({ to, children }) => { const history = useHistory(); const onClick = (event: React.MouseEvent) => { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/step_detail_link.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/step_detail_link.tsx index fa6d0b4c3f8bb..8c0211806d829 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/step_detail_link.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/step_detail_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ReactRouterEuiButtonEmpty } from './react_router_helpers'; interface StepDetailLinkProps { @@ -19,7 +19,11 @@ interface StepDetailLinkProps { stepIndex: number; } -export const StepDetailLink: FC = ({ children, checkGroupId, stepIndex }) => { +export const StepDetailLink: FC> = ({ + children, + checkGroupId, + stepIndex, +}) => { const to = `/journey/${checkGroupId}/step/${stepIndex}`; return ( diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx index f86b819e78e3b..c34c44241549a 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import url from 'url'; import { EuiButtonEmpty } from '@elastic/eui'; import rison from '@kbn/rison'; @@ -46,7 +46,12 @@ export const getMLJobLinkHref = ({ basePath, monitorId, dateRange }: Props) => { }); }; -export const MLJobLink: React.FC = ({ basePath, monitorId, dateRange, children }) => { +export const MLJobLink: FC> = ({ + basePath, + monitorId, + dateRange, + children, +}) => { const href = getMLJobLinkHref({ basePath, monitorId, dateRange }); return ( = ({ +export const WaterfallProvider: FC> = ({ children, data, markerItems, diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/synthetics/code_block_accordion.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/synthetics/code_block_accordion.tsx index 225ba1041c263..f53d9016007b8 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/synthetics/code_block_accordion.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/synthetics/code_block_accordion.tsx @@ -6,7 +6,7 @@ */ import { EuiAccordion, EuiCodeBlock } from '@elastic/eui'; -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; interface Props { buttonContent: string; @@ -20,7 +20,7 @@ interface Props { * Utility for showing `EuiAccordions` with code blocks which we use frequently in synthetics to display * stack traces, long error messages, and synthetics journey code. */ -export const CodeBlockAccordion: FC = ({ +export const CodeBlockAccordion: FC> = ({ buttonContent, children, id, diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_data_view_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_data_view_context.tsx index f6da88051ca35..edcf638b4414f 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_data_view_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_data_view_context.tsx @@ -5,16 +5,18 @@ * 2.0. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, FC, PropsWithChildren } from 'react'; import { useFetcher } from '@kbn/observability-shared-plugin/public'; import { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public'; import { useHasData } from '../components/overview/empty_state/use_has_data'; export const UptimeDataViewContext = createContext({} as DataView); -export const UptimeDataViewContextProvider: React.FC<{ - dataViews: DataViewsPublicPluginStart; -}> = ({ children, dataViews }) => { +export const UptimeDataViewContextProvider: FC< + PropsWithChildren<{ + dataViews: DataViewsPublicPluginStart; + }> +> = ({ children, dataViews }) => { const { settings, data: indexStatus } = useHasData(); const heartbeatIndices = settings?.heartbeatIndices || ''; diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx index 12d904ae3c4b5..130b9ab449644 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { createContext, useContext, useMemo, useState } from 'react'; +import React, { createContext, useContext, useMemo, useState, FC, PropsWithChildren } from 'react'; interface UptimeRefreshContext { lastRefresh: number; @@ -21,7 +21,7 @@ const defaultContext: UptimeRefreshContext = { export const UptimeRefreshContext = createContext(defaultContext); -export const UptimeRefreshContextProvider: React.FC = ({ children }) => { +export const UptimeRefreshContextProvider: FC = ({ children }) => { const [lastRefresh, setLastRefresh] = useState(Date.now()); const refreshApp = () => { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_settings_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_settings_context.tsx index d192f7327879c..3bb8c03104ae1 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_settings_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_settings_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { createContext, useContext, useMemo } from 'react'; +import React, { createContext, useContext, useMemo, PropsWithChildren } from 'react'; import { UptimeAppProps } from '../app/uptime_app'; import { CLIENT_DEFAULTS, CONTEXT_DEFAULTS } from '../../../common/constants'; import { CommonlyUsedRange } from '../components/common/uptime_date_picker'; @@ -41,7 +41,10 @@ const defaultContext: UptimeSettingsContextValues = { }; export const UptimeSettingsContext = createContext(defaultContext); -export const UptimeSettingsContextProvider: React.FC = ({ children, ...props }) => { +export const UptimeSettingsContextProvider: React.FC> = ({ + children, + ...props +}) => { const { basePath, isApmAvailable, isInfraAvailable, isLogsAvailable, commonlyUsedRanges, isDev } = props; diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_startup_plugins_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_startup_plugins_context.tsx index 76754a52a3dfb..12612720d0374 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_startup_plugins_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_startup_plugins_context.tsx @@ -5,14 +5,15 @@ * 2.0. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, PropsWithChildren } from 'react'; import { ClientPluginsStart } from '../../plugin'; export const UptimeStartupPluginsContext = createContext>({}); -export const UptimeStartupPluginsContextProvider: React.FC> = ({ - children, - ...props -}) => ; +export const UptimeStartupPluginsContextProvider: React.FC< + PropsWithChildren> +> = ({ children, ...props }) => ( + +); export const useUptimeStartPlugins = () => useContext(UptimeStartupPluginsContext); diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_theme_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_theme_context.tsx index e50c076423dfb..97787ba9db4e9 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_theme_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_theme_context.tsx @@ -6,7 +6,7 @@ */ import { euiLightVars, euiDarkVars } from '@kbn/ui-theme'; -import React, { createContext, useMemo } from 'react'; +import React, { createContext, useMemo, FC, PropsWithChildren } from 'react'; import { DARK_THEME, LIGHT_THEME, PartialTheme, Theme } from '@elastic/charts'; import { UptimeAppColors } from '../app/uptime_app'; @@ -44,7 +44,10 @@ interface ThemeContextProps { darkMode: boolean; } -export const UptimeThemeContextProvider: React.FC = ({ darkMode, children }) => { +export const UptimeThemeContextProvider: FC> = ({ + darkMode, + children, +}) => { let colors: UptimeAppColors; if (darkMode) { colors = { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx index 853d35fde6eab..79cf01afc6670 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx @@ -7,12 +7,12 @@ import { renderHook } from '@testing-library/react-hooks'; import { createMemoryHistory } from 'history'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import * as reactRedux from 'react-redux'; import { useOverviewFilterCheck } from './use_overview_filter_check'; import { MockRouter } from '../lib/helper/rtl_helpers'; -function getWrapper(customSearch?: string): React.FC { +function getWrapper(customSearch?: string): FC { return ({ children }) => { const { location, ...rest } = createMemoryHistory(); return ( diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/lib/helper/helper_with_redux.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/lib/helper/helper_with_redux.tsx index 662fdad1a98d9..ab5968da12673 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/lib/helper/helper_with_redux.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/lib/helper/helper_with_redux.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { Store } from 'redux'; import { createStore as createReduxStore, applyMiddleware } from 'redux'; @@ -23,11 +23,13 @@ export const createRealStore = (): Store => { return store; }; -export const MountWithReduxProvider: React.FC<{ - state?: AppState; - useRealStore?: boolean; - store?: Store; -}> = ({ children, state, store, useRealStore }) => { +export const MountWithReduxProvider: FC< + PropsWithChildren<{ + state?: AppState; + useRealStore?: boolean; + store?: Store; + }> +> = ({ children, state, store, useRealStore }) => { const newStore = useRealStore ? createRealStore() : { diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx index 32a33055ba50a..4a5abb90dce72 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import type { useKibana } from '../../common/lib/kibana'; @@ -77,4 +78,4 @@ export const getMockedKibanaConfig = (permissionType: unknown) => }, } as unknown as ReturnType); -export const mockCasesContext: React.FC = (props) => <>{props?.children ?? null}; +export const mockCasesContext: FC = (props) => <>{props?.children ?? null}; diff --git a/x-pack/plugins/reporting/public/lib/default_status_context.tsx b/x-pack/plugins/reporting/public/lib/default_status_context.tsx index 23609e7e0a6ab..a53cd0d0e2198 100644 --- a/x-pack/plugins/reporting/public/lib/default_status_context.tsx +++ b/x-pack/plugins/reporting/public/lib/default_status_context.tsx @@ -6,7 +6,7 @@ */ import { ClientConfigType } from '@kbn/reporting-public'; -import React, { createContext, FunctionComponent } from 'react'; +import React, { createContext, FC, PropsWithChildren } from 'react'; import { IlmPolicyStatusContextProvider } from './ilm_policy_status_context'; const PolicyStatusContext = createContext(undefined); @@ -15,10 +15,9 @@ interface PolicyStatusContextProviderProps { config: ClientConfigType; } -export const PolicyStatusContextProvider: FunctionComponent = ({ - children, - ...props -}) => { +export const PolicyStatusContextProvider: FC< + PropsWithChildren +> = ({ children, ...props }) => { return props.config.statefulSettings.enabled ? ( {children} ) : ( diff --git a/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx b/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx index 9b3b7e27b6457..336323a7e56f9 100644 --- a/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx +++ b/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { createContext, useContext } from 'react'; import type { IlmPolicyStatusResponse } from '@kbn/reporting-common/types'; import { useCheckIlmPolicyStatus } from '@kbn/reporting-public'; @@ -20,7 +20,7 @@ interface ContextValue { const IlmPolicyStatusContext = createContext(undefined); -export const IlmPolicyStatusContextProvider: FunctionComponent = ({ children }) => { +export const IlmPolicyStatusContextProvider: FC = ({ children }) => { const { isLoading, data, resendRequest: recheckStatus } = useCheckIlmPolicyStatus(); return ( diff --git a/x-pack/plugins/saved_objects_tagging/public/management/mount_section.tsx b/x-pack/plugins/saved_objects_tagging/public/management/mount_section.tsx index 7c55d95a07637..27597189a5797 100644 --- a/x-pack/plugins/saved_objects_tagging/public/management/mount_section.tsx +++ b/x-pack/plugins/saved_objects_tagging/public/management/mount_section.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import ReactDOM from 'react-dom'; import { CoreSetup, ApplicationStart } from '@kbn/core/public'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; @@ -24,9 +24,11 @@ interface MountSectionParams { title: string; } -const RedirectToHomeIfUnauthorized: FC<{ - applications: ApplicationStart; -}> = ({ applications, children }) => { +const RedirectToHomeIfUnauthorized: FC< + PropsWithChildren<{ + applications: ApplicationStart; + }> +> = ({ applications, children }) => { const allowed = applications.capabilities?.management?.kibana?.tags ?? false; if (!allowed) { applications.navigateToApp('home'); diff --git a/x-pack/plugins/search_notebooks/public/components/title_panel.tsx b/x-pack/plugins/search_notebooks/public/components/title_panel.tsx index 0926af8f70537..86a22d59a8178 100644 --- a/x-pack/plugins/search_notebooks/public/components/title_panel.tsx +++ b/x-pack/plugins/search_notebooks/public/components/title_panel.tsx @@ -4,10 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiHorizontalRule, EuiPanel, EuiText } from '@elastic/eui'; -export const TitlePanel: React.FC = ({ children }) => ( +export const TitlePanel: FC = ({ children }) => ( <> diff --git a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx index cb5b2fb78eb56..d70b2cfc77005 100644 --- a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx +++ b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { render, screen } from '@testing-library/react'; import { SourcesPanelSidebar } from './sources_panel_sidebar'; import { useSourceIndicesFields } from '../../hooks/use_source_indices_field'; @@ -19,7 +19,7 @@ jest.mock('../../hooks/use_query_indices', () => ({ useQueryIndices: jest.fn(), })); -const Wrapper: React.FC = ({ children }) => { +const Wrapper: FC = ({ children }) => { return ( <> {children} diff --git a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx index 9195f8295e735..54f2610e453ac 100644 --- a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx +++ b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { render, screen } from '@testing-library/react'; import { SourcesPanelForStartChat } from './sources_panel_for_start_chat'; import { useSourceIndicesFields } from '../../hooks/use_source_indices_field'; @@ -28,7 +28,7 @@ jest.mock('../../hooks/use_kibana', () => ({ })), })); -const Wrapper: React.FC = ({ children }) => { +const Wrapper: FC = ({ children }) => { return ( <> {children} diff --git a/x-pack/plugins/search_playground/public/components/start_chat_panel.tsx b/x-pack/plugins/search_playground/public/components/start_chat_panel.tsx index 4c19b3e28d1ba..c08d9bdbeeafd 100644 --- a/x-pack/plugins/search_playground/public/components/start_chat_panel.tsx +++ b/x-pack/plugins/search_playground/public/components/start_chat_panel.tsx @@ -14,16 +14,17 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; interface StartChatPanelProps { + children: React.ReactNode; title: string; description: string | React.ReactNode; isValid?: boolean; } -export const StartChatPanel: React.FC = ({ +export const StartChatPanel: FC> = ({ title, description, children, diff --git a/x-pack/plugins/search_playground/public/providers/playground_provider.tsx b/x-pack/plugins/search_playground/public/providers/playground_provider.tsx index 0988336404cd8..e9e6e7d2a8000 100644 --- a/x-pack/plugins/search_playground/public/providers/playground_provider.tsx +++ b/x-pack/plugins/search_playground/public/providers/playground_provider.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { FormProvider, useForm } from 'react-hook-form'; import { ChatForm, ChatFormFields } from '../types'; @@ -13,10 +13,11 @@ import { ChatForm, ChatFormFields } from '../types'; const queryClient = new QueryClient({}); export interface PlaygroundProviderProps { + children: React.ReactNode; defaultValues?: Partial>; } -export const PlaygroundProvider: React.FC = ({ +export const PlaygroundProvider: FC> = ({ children, defaultValues, }) => { diff --git a/x-pack/plugins/security/public/account_management/account_management_app.tsx b/x-pack/plugins/security/public/account_management/account_management_app.tsx index e648e6409536a..6a812cf3ccb83 100644 --- a/x-pack/plugins/security/public/account_management/account_management_app.tsx +++ b/x-pack/plugins/security/public/account_management/account_management_app.tsx @@ -6,8 +6,7 @@ */ import type { History } from 'history'; -import type { FunctionComponent } from 'react'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import type { @@ -78,7 +77,7 @@ export interface ProvidersProps { onChange?: BreadcrumbsChangeHandler; } -export const Providers: FunctionComponent = ({ +export const Providers: FC> = ({ services, history, authc, diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx index 9dcc5b52417b1..2bbcf4b03623e 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx @@ -7,8 +7,7 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { mount } from 'enzyme'; -import type { FunctionComponent } from 'react'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { coreMock, scopedHistoryMock } from '@kbn/core/public/mocks'; @@ -25,7 +24,7 @@ const coreStart = coreMock.createStart(); let history = scopedHistoryMock.create(); const authc = securityMock.createSetup().authc; -const wrapper: FunctionComponent = ({ children }) => ( +const wrapper: FC = ({ children }) => ( = (props) => ( +export const AuthenticationStatePage: FC> = (props) => (
    diff --git a/x-pack/plugins/security/public/components/breadcrumb.tsx b/x-pack/plugins/security/public/components/breadcrumb.tsx index 8027147cf22da..3ad82b6163d96 100644 --- a/x-pack/plugins/security/public/components/breadcrumb.tsx +++ b/x-pack/plugins/security/public/components/breadcrumb.tsx @@ -71,7 +71,7 @@ export type BreadcrumbsChangeHandler = (breadcrumbs: BreadcrumbProps[]) => void; * * ``` */ -export const BreadcrumbsProvider: FunctionComponent = ({ +export const BreadcrumbsProvider: FC> = ({ children, onChange, }) => { @@ -120,7 +120,7 @@ export interface InnerBreadcrumbProps { breadcrumb: BreadcrumbProps; } -export const InnerBreadcrumb: FunctionComponent = ({ +export const InnerBreadcrumb: FC> = ({ breadcrumb, children, }) => { diff --git a/x-pack/plugins/security/public/components/doc_link.tsx b/x-pack/plugins/security/public/components/doc_link.tsx index c23a8f31d4b58..1aa399fb0cc70 100644 --- a/x-pack/plugins/security/public/components/doc_link.tsx +++ b/x-pack/plugins/security/public/components/doc_link.tsx @@ -6,7 +6,7 @@ */ import { EuiLink } from '@elastic/eui'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useCallback } from 'react'; import type { DocLinksStart } from '@kbn/core/public'; @@ -53,7 +53,7 @@ export interface DocLinkProps { doc: string; } -export const DocLink: FunctionComponent = ({ app, doc, children }) => { +export const DocLink: FC> = ({ app, doc, children }) => { const [, getDocLink] = useDocLinks(); return ( diff --git a/x-pack/plugins/security/public/components/form_label.tsx b/x-pack/plugins/security/public/components/form_label.tsx index e1e646a4412ed..85126e8f654db 100644 --- a/x-pack/plugins/security/public/components/form_label.tsx +++ b/x-pack/plugins/security/public/components/form_label.tsx @@ -7,7 +7,7 @@ import { EuiIcon } from '@elastic/eui'; import { useFormikContext } from 'formik'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { useEffect } from 'react'; import { useFormChangesContext } from './form_changes'; @@ -36,7 +36,7 @@ export interface FormLabelProps { * @throws Error if not a child of a `` component. * @throws Error if not a child of a `` component. */ -export const FormLabel: FunctionComponent = (props) => { +export const FormLabel: FC> = (props) => { const formik = useFormikContext(); const { report } = useFormChangesContext(); diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx index 77d71f1f6db91..84be05ea9b946 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx @@ -7,7 +7,7 @@ import { EuiAccordion, EuiErrorBoundary, EuiSpacer, EuiText, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -21,7 +21,7 @@ export interface ApiKeysEmptyPromptProps { readOnly?: boolean; } -export const ApiKeysEmptyPrompt: FunctionComponent = ({ +export const ApiKeysEmptyPrompt: FC> = ({ error, readOnly, children, diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx index 0f717ecfe46c9..3efbc5f2efd77 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx @@ -21,7 +21,7 @@ import { EuiToolTip, } from '@elastic/eui'; import moment from 'moment-timezone'; -import type { FunctionComponent } from 'react'; +import type { FunctionComponent, PropsWithChildren } from 'react'; import React, { useEffect, useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import useAsyncFn from 'react-use/lib/useAsyncFn'; @@ -705,7 +705,10 @@ export interface TimeToolTipProps { timestamp: number; } -export const TimeToolTip: FunctionComponent = ({ timestamp, children }) => { +export const TimeToolTip: FunctionComponent> = ({ + timestamp, + children, +}) => { return ( {children ?? moment(timestamp).fromNow()} diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx index 08fcbaac520e3..3940c25bf6c43 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx @@ -6,7 +6,7 @@ */ import type { History } from 'history'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; @@ -82,7 +82,7 @@ export interface ProvidersProps { onChange?: BreadcrumbsChangeHandler; } -export const Providers: FunctionComponent = ({ +export const Providers: FC> = ({ services, history, authc, diff --git a/x-pack/plugins/security/public/management/users/users_management_app.tsx b/x-pack/plugins/security/public/management/users/users_management_app.tsx index 4935db6273bb6..aac45ae6c7934 100644 --- a/x-pack/plugins/security/public/management/users/users_management_app.tsx +++ b/x-pack/plugins/security/public/management/users/users_management_app.tsx @@ -6,8 +6,7 @@ */ import type { History } from 'history'; -import type { FunctionComponent } from 'react'; -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { Redirect } from 'react-router-dom'; @@ -137,7 +136,7 @@ export interface ProvidersProps { onChange?: BreadcrumbsChangeHandler; } -export const Providers: FunctionComponent = ({ +export const Providers: FC> = ({ services, history, authc, diff --git a/x-pack/plugins/security/public/nav_control/nav_control_service.tsx b/x-pack/plugins/security/public/nav_control/nav_control_service.tsx index ebfe41aeafc0c..1a209e14dc2b7 100644 --- a/x-pack/plugins/security/public/nav_control/nav_control_service.tsx +++ b/x-pack/plugins/security/public/nav_control/nav_control_service.tsx @@ -6,7 +6,7 @@ */ import { sortBy } from 'lodash'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import ReactDOM from 'react-dom'; import type { Subscription } from 'rxjs'; @@ -143,7 +143,7 @@ export interface ProvidersProps { securityApiClients: SecurityApiClients; } -export const Providers: FunctionComponent = ({ +export const Providers: FC> = ({ authc, services, securityApiClients, diff --git a/x-pack/plugins/security/public/ui_api/components.tsx b/x-pack/plugins/security/public/ui_api/components.tsx index 7ab626bad1571..29e67af5e706d 100644 --- a/x-pack/plugins/security/public/ui_api/components.tsx +++ b/x-pack/plugins/security/public/ui_api/components.tsx @@ -30,7 +30,7 @@ export const getComponents = ({ core }: GetComponentsOptions) => { /** * Returns a function that creates a lazy-loading version of a component. */ - function wrapLazy(fn: () => Promise>) { + function wrapLazy(fn: () => Promise>>) { return (props: JSX.IntrinsicAttributes & PropsWithRef>) => ( ); diff --git a/x-pack/plugins/security/public/ui_api/lazy_wrapper.tsx b/x-pack/plugins/security/public/ui_api/lazy_wrapper.tsx index 3ac1901511b20..0779b98ab3e47 100644 --- a/x-pack/plugins/security/public/ui_api/lazy_wrapper.tsx +++ b/x-pack/plugins/security/public/ui_api/lazy_wrapper.tsx @@ -13,7 +13,7 @@ import type { CoreStart } from '@kbn/core/public'; import { SuspenseErrorBoundary } from '../suspense_error_boundary'; interface InternalProps { - fn: () => Promise>; + fn: () => Promise>>; core: CoreStart; props: JSX.IntrinsicAttributes & PropsWithRef>; } diff --git a/x-pack/plugins/security_solution/public/assistant/provider.tsx b/x-pack/plugins/security_solution/public/assistant/provider.tsx index e11c39c00cf18..a1be7d7888f05 100644 --- a/x-pack/plugins/security_solution/public/assistant/provider.tsx +++ b/x-pack/plugins/security_solution/public/assistant/provider.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useEffect } from 'react'; import { parse } from '@kbn/datemath'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -114,7 +115,7 @@ export const createConversations = async ( /** * This component configures the Elastic AI Assistant context provider for the Security Solution app. */ -export const AssistantProvider: React.FC = ({ children }) => { +export const AssistantProvider: FC = ({ children }) => { const { http, notifications, diff --git a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx index 5e929312c3da2..e6e8222468bda 100644 --- a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx @@ -46,7 +46,7 @@ export interface SendToTimelineButtonProps { isDisabled?: boolean; } -export const SendToTimelineButton: React.FunctionComponent = ({ +export const SendToTimelineButton: FC> = ({ asEmptyButton, children, dataProviders, diff --git a/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx b/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx index 605e998fe678f..c04f8536c4eb8 100644 --- a/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx @@ -5,12 +5,13 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; export const createQueryWrapperMock = (): { queryClient: QueryClient; - wrapper: React.FC; + wrapper: FC; } => { const queryClient = new QueryClient({ defaultOptions: { diff --git a/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx b/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx index 50843302c621d..2982c7b87e3d6 100644 --- a/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import type { Dispatch } from 'redux'; @@ -13,7 +13,7 @@ import type { ILicense } from '@kbn/licensing-plugin/common/types'; import { licenseService } from '../../hooks/use_license'; import type { AppAction } from '../../store/actions'; -export const CurrentLicense: FC = memo(({ children }) => { +export const CurrentLicense = memo(({ children }) => { const dispatch = useDispatch>(); useEffect(() => { const subscription = licenseService diff --git a/x-pack/plugins/security_solution/public/common/components/empty_prompt/empty_prompt.tsx b/x-pack/plugins/security_solution/public/common/components/empty_prompt/empty_prompt.tsx index 853b064233c3b..6b36f64d27ea4 100644 --- a/x-pack/plugins/security_solution/public/common/components/empty_prompt/empty_prompt.tsx +++ b/x-pack/plugins/security_solution/public/common/components/empty_prompt/empty_prompt.tsx @@ -67,7 +67,7 @@ const footerStyles = css` margin: 20px auto 0; `; -export const EmptyPromptComponent: React.FC = memo(() => { +export const EmptyPromptComponent = memo(() => { const { euiTheme } = useEuiTheme(); const { navigateTo } = useNavigateTo(); diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx index e1d0751337fbf..892154c03c2e8 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { memo, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { useDispatch } from 'react-redux'; @@ -16,7 +17,7 @@ import { timelineActions } from '../../../timelines/store'; * This component should be used above all routes, but below the Provider. * It dispatches actions when the URL is changed. */ -export const RouteCapture = memo(({ children }) => { +export const RouteCapture = memo(({ children }) => { const location: AppLocation = useLocation(); const dispatch = useDispatch(); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx index ce22e6e09b433..6c8980e012ed7 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx @@ -6,6 +6,7 @@ */ import styled from 'styled-components'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { EuiTitle, EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import type { HostRisk, UserRisk } from '../../../../entity_analytics/api/types'; @@ -27,7 +28,7 @@ const UppercaseEuiTitle = styled(EuiTitle)` text-transform: uppercase; `; -const ThreatSummaryPanelTitle: React.FC = ({ children }) => ( +const ThreatSummaryPanelTitle: FC = ({ children }) => (
    {children}
    diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/overview_card.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/overview_card.tsx index 0501031f9ad68..ffebdf330a3f1 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/overview_card.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/overview_card.tsx @@ -6,6 +6,7 @@ */ import { EuiFlexGroup, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; @@ -54,7 +55,7 @@ interface OverviewCardProps { title: string; } -export const OverviewCard: React.FC = ({ title, children }) => ( +export const OverviewCard: FC> = ({ title, children }) => ( {title} @@ -80,7 +81,7 @@ type OverviewCardWithActionsProps = OverviewCardProps & { dataTestSubj?: string; }; -export const OverviewCardWithActions: React.FC = ({ +export const OverviewCardWithActions: FC> = ({ title, children, contextId, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx index d1a0db8772bae..b48f23773bfcc 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useCallback } from 'react'; import { EuiButton, EuiButtonEmpty } from '@elastic/eui'; import type { IconType } from '@elastic/eui'; @@ -32,10 +33,11 @@ export interface InvestigateInTimelineButtonProps { keepDataView?: boolean; isDisabled?: boolean; iconType?: IconType; + children?: React.ReactNode; } -export const InvestigateInTimelineButton: React.FunctionComponent< - InvestigateInTimelineButtonProps +export const InvestigateInTimelineButton: FC< + PropsWithChildren > = ({ asEmptyButton, children, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx index d6f7e8d531729..0e8183df7ff29 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { createContext, useContext } from 'react'; import { useThrottledResizeObserver } from '../utils'; @@ -14,7 +15,7 @@ const EventDetailsWidthContext = createContext(DEFAULT_WIDTH); export const useEventDetailsWidthContext = () => useContext(EventDetailsWidthContext); -export const EventDetailsWidthProvider = React.memo(({ children }) => { +export const EventDetailsWidthProvider = React.memo(({ children }) => { const { ref, width } = useThrottledResizeObserver(); return ( diff --git a/x-pack/plugins/security_solution/public/common/components/health_truncate_text/index.tsx b/x-pack/plugins/security_solution/public/common/components/health_truncate_text/index.tsx index 57a893cb1eadc..e1c62e90f8ff6 100644 --- a/x-pack/plugins/security_solution/public/common/components/health_truncate_text/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/health_truncate_text/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; import styled from 'styled-components'; import type { EuiHealthProps } from '@elastic/eui'; @@ -26,7 +27,7 @@ interface HealthTruncateTextProps { * @param healthColor - color for EuiHealth component * @param tooltipContent - tooltip content */ -export const HealthTruncateText: React.FC = ({ +export const HealthTruncateText: React.FC> = ({ tooltipContent, children, healthColor, diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx index 4d0049cb9cd62..08d3fb6f2b757 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx @@ -5,8 +5,11 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; export const ProductSwitch = jest .fn() - .mockImplementation(({ children }) =>
    {children}
    ); + .mockImplementation(({ children }: PropsWithChildren) => ( +
    {children}
    + )); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx index c1707bf5057b6..fce63a07ce506 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx @@ -5,8 +5,11 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; export const TogglePanel = jest .fn() - .mockImplementation(({ children }) =>
    {children}
    ); + .mockImplementation(({ children }: PropsWithChildren) => ( +
    {children}
    + )); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/context/step_context.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/context/step_context.tsx index 28d05526d041e..6e06d85e471b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/context/step_context.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/context/step_context.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; import type { OnboardingHubStepLinkClickedParams } from '../../../../lib/telemetry/events/onboarding/types'; import type { @@ -26,7 +27,10 @@ export interface StepContextType { const StepContext = React.createContext(null); -export const StepContextProvider: React.FC = ({ children, ...others }) => { +export const StepContextProvider: React.FC> = ({ + children, + ...others +}) => { return {children}; }; diff --git a/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx index aedfa151c362c..9dd3accd15e32 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { SyntheticEvent } from 'react'; +import type { SyntheticEvent, PropsWithChildren } from 'react'; import React, { useCallback, useMemo, useState } from 'react'; import type { EuiButtonIcon, @@ -29,10 +29,10 @@ export interface ReputationLinkSetting { url_template: string; } export const LinkButton: React.FC< - PropsForButton | PropsForAnchor + PropsWithChildren | PropsForAnchor> > = ({ children, ...props }) => {children}; -export const LinkAnchor: React.FC = ({ children, ...props }) => ( +export const LinkAnchor: React.FC> = ({ children, ...props }) => ( {children} ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx index 0bd25283451a4..8fb9a9d9b0b3c 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { useState, useEffect } from 'react'; import type { MlCapabilitiesResponse } from '@kbn/ml-plugin/public'; @@ -29,7 +30,7 @@ export const MlCapabilitiesContext = React.createContext MlCapabilitiesContext.displayName = 'MlCapabilitiesContext'; -export const MlCapabilitiesProvider = React.memo<{ children: JSX.Element }>(({ children }) => { +export const MlCapabilitiesProvider = React.memo(({ children }) => { const [capabilities, setCapabilities] = useState( emptyMlCapabilitiesProvider ); diff --git a/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx b/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx index 07a94463e2d81..65e35b1f42443 100644 --- a/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx @@ -36,7 +36,7 @@ interface SecurityRoutePageWrapperProps { * * ``` */ -export const SecurityRoutePageWrapper: React.FC = ({ +export const SecurityRoutePageWrapper: FC> = ({ children, pageName, redirectOnMissing, diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx index 835959a85bbd9..06ce7a64c0ac5 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx @@ -6,6 +6,7 @@ */ import { renderHook } from '@testing-library/react-hooks'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { SecurityPageName } from '../../../common'; import { UpsellingService } from '@kbn/security-solution-upselling/service'; @@ -29,7 +30,7 @@ jest.mock('../lib/kibana', () => { }); const TestComponent = () =>
    {'TEST 1 2 3'}
    ; -const RenderWrapper: React.FunctionComponent = ({ children }) => { +const RenderWrapper: FC = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx index 05bc70589a4b3..45066b902873c 100644 --- a/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx @@ -6,6 +6,7 @@ */ import { euiLightVars } from '@kbn/ui-theme'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { Subject } from 'rxjs'; @@ -93,7 +94,7 @@ const KibanaReactContext = createKibanaReactContext(coreMock); * It is a simplified version of TestProvidersComponent. * To reuse TestProvidersComponent here, we need to remove all references to jest from mocks. */ -export const StorybookProviders: React.FC = ({ children }) => { +export const StorybookProviders: FC = ({ children }) => { const store = createMockStore(); return ( diff --git a/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx b/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx index 02bccd69eb253..e724f961625a7 100644 --- a/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import type { Tag } from '@kbn/saved-objects-tagging-plugin/common'; import { useFetchSecurityTags } from '../containers/use_fetch_security_tags'; @@ -18,7 +19,7 @@ export interface DashboardContextType { const DashboardContext = React.createContext({ securityTags: null }); -export const DashboardContextProvider: React.FC = ({ children }) => { +export const DashboardContextProvider: FC = ({ children }) => { const { tags, isLoading } = useFetchSecurityTags(); const securityTags = isLoading || !tags ? null : tags; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/preview_logs.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/preview_logs.tsx index 1c01a0491e92c..912df2453cc46 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/preview_logs.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/preview_logs.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { Fragment, useMemo } from 'react'; import { EuiCallOut, EuiText, EuiSpacer, EuiAccordion } from '@elastic/eui'; import type { RulePreviewLogs } from '../../../../../common/api/detection_engine'; @@ -72,7 +73,7 @@ const PreviewLogsComponent: React.FC = ({ logs, hasNoiseWarnin export const PreviewLogs = React.memo(PreviewLogsComponent); PreviewLogs.displayName = 'PreviewLogs'; -const LogAccordion: React.FC = ({ logs, isError, children }) => { +const LogAccordion: FC> = ({ logs, isError, children }) => { const firstLog = logs[0]; if (!(children || firstLog)) return null; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx index 3139cb5478907..b21a51b22b44d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useMemo } from 'react'; import classNames from 'classnames'; import { css, Global } from '@emotion/react'; @@ -78,7 +79,7 @@ const useTokens = ( highlight: false, enhancers: [ /* - This custom "markEdits" function is a slightly modified version of "markEdits" + This custom "markEdits" function is a slightly modified version of "markEdits" enhancer from react-diff-view with added support for word-level highlighting. */ markEdits(hunks, diffMethod), @@ -145,7 +146,7 @@ const convertToDiffFile = (oldSource: string, newSource: string) => { return diffFile; }; -const CustomStyles: React.FC = ({ children }) => { +const CustomStyles: FC = ({ children }) => { const { euiTheme } = useEuiTheme(); const customCss = css` diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx index 84779ccb91b00..c16e18f009dd9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { EuiThemeProvider } from '@elastic/eui'; import { render, screen } from '@testing-library/react'; @@ -18,7 +19,7 @@ import { COLORS } from './constants'; /* Finds an element with a text content that exactly matches the passed argument. - Handly because React Testing Library's doesn't provide an easy way to search by + Handly because React Testing Library's doesn't provide an easy way to search by text if the text is split into multiple DOM elements. */ function findChildByTextContent(parent: Element, textContent: string): HTMLElement { @@ -63,7 +64,7 @@ describe('Rule upgrade workflow: viewing rule changes in JSON diff view', () => delete oldRule.license; newRule.license = 'GPLv3'; - const ThemeWrapper: React.FC<{}> = ({ children }) => ( + const ThemeWrapper: FC = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx index b5806e770a067..dc783c15f79f6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useMemo, useState, useEffect } from 'react'; import styled from 'styled-components'; import { css } from '@emotion/css'; @@ -100,7 +101,7 @@ const tabPaddingClassName = css` padding: 0 ${euiThemeVars.euiSizeM} ${euiThemeVars.euiSizeXL} ${euiThemeVars.euiSizeM}; `; -export const TabContentPadding: React.FC = ({ children }) => ( +export const TabContentPadding: FC = ({ children }) => (
    {children}
    ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx index 5b90a457a6bd4..6be5fff720734 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { render, screen } from '@testing-library/react'; @@ -15,7 +15,7 @@ import { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; import type { DryRunResult } from './types'; import { BulkActionTypeEnum } from '../../../../../../common/api/detection_engine/rule_management'; -const Wrapper: FC = ({ children }) => { +const Wrapper: FC = ({ children }) => { return ( <>{children} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx index 5459968b6c497..cc1e9030b0ff6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; @@ -41,7 +42,7 @@ describe('useExecutionEvents', () => { }, }, }); - const wrapper: React.FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx index ddb553998584f..2178401fa1f37 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; @@ -36,7 +37,7 @@ describe('useExecutionResults', () => { }, }, }); - const wrapper: React.FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx b/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx index 387638d394e6c..fc9b3c35a5b48 100644 --- a/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { useHostIsolationAction } from './use_host_isolation_action'; @@ -33,7 +34,7 @@ describe('useHostIsolationAction', () => { ])('works with %s hook', (name, hook) => { const createReactQueryWrapper = () => { const queryClient = new QueryClient(); - const wrapper: React.FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx index c58d05ce81b8f..da29cb140ac24 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; @@ -35,7 +36,7 @@ describe('useInstalledIntegrations', () => { }, }, }); - const wrapper: React.FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx index 76435bb83b850..8cf79337ac84b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { render } from '@testing-library/react'; @@ -47,7 +48,7 @@ const queryClient = new QueryClient({ }, }); -const ContextWrapper: React.FC = ({ children }) => ( +const ContextWrapper: FC = ({ children }) => ( = memo( +export const RenderCellValue: React.FC> = memo( function RenderCellValue(props) { const { columnId, diff --git a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embeddable.tsx b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embeddable.tsx index e075c03f9b504..55950b2bffff5 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embeddable.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embeddable.tsx @@ -6,6 +6,7 @@ */ import { EuiPanel } from '@elastic/eui'; +import type { PropsWithChildren } from 'react'; import React from 'react'; import styled from 'styled-components'; @@ -18,7 +19,7 @@ export interface EmbeddableProps { children: React.ReactNode; } -export const Embeddable = React.memo(({ children }) => ( +export const Embeddable = React.memo>(({ children }) => (
    {children} diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx index 661ae2eab58ab..557c8bae274fe 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx @@ -6,7 +6,7 @@ */ import type { ReactElement, ReactNode } from 'react'; -import React, { type VFC, useMemo, useCallback } from 'react'; +import React, { type FC, useMemo, useCallback } from 'react'; import { type Criteria, EuiBasicTable, formatDate } from '@elastic/eui'; import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import type { Filter } from '@kbn/es-query'; @@ -131,7 +131,7 @@ export interface CorrelationsDetailsAlertsTableProps { /** * Renders paginated alert array based on the provided alertIds */ -export const CorrelationsDetailsAlertsTable: VFC = ({ +export const CorrelationsDetailsAlertsTable: FC = ({ title, loading, alertIds, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx index b8bb13fd1bd9f..65fff6a9e7299 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx @@ -29,7 +29,7 @@ export interface RelatedAlertsByAncestryProps { /** * Show related alerts by ancestry in an expandable panel with a table */ -export const RelatedAlertsByAncestry: React.VFC = ({ +export const RelatedAlertsByAncestry: React.FC = ({ documentId, indices, scopeId, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.tsx index 42c9d910d93c6..d58e36be60247 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.tsx @@ -29,7 +29,7 @@ export interface RelatedAlertsBySameSourceEventProps { /** * Show related alerts by same source event in an expandable panel with a table */ -export const RelatedAlertsBySameSourceEvent: React.VFC = ({ +export const RelatedAlertsBySameSourceEvent: React.FC = ({ originalEventId, scopeId, eventId, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.tsx index 1aa5a2b9dd619..88507d8262b32 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.tsx @@ -29,7 +29,7 @@ export interface RelatedAlertsBySessionProps { /** * Show related alerts by session in an expandable panel with a table */ -export const RelatedAlertsBySession: React.VFC = ({ +export const RelatedAlertsBySession: React.FC = ({ entityId, scopeId, eventId, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx index a9ed2ac935b5d..bef7b15a7a971 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx @@ -61,7 +61,7 @@ export interface RelatedCasesProps { /** * */ -export const RelatedCases: React.VFC = ({ eventId }) => { +export const RelatedCases: React.FC = ({ eventId }) => { const { loading, error, data, dataCount } = useFetchRelatedCases({ eventId }); if (error) { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx index edb05f02ff204..c3ac766d14cc2 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx @@ -34,7 +34,7 @@ export interface SuppressedAlertsProps { /** * Displays number of suppressed alerts and investigate in timeline icon */ -export const SuppressedAlerts: React.VFC = ({ +export const SuppressedAlerts: React.FC = ({ dataAsNestedObject, alertSuppressionCount, }) => { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/tour.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/tour.tsx index 8668f6477f549..e1719be5b20a5 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/tour.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/tour.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useMemo } from 'react'; import { getField } from '../../shared/utils'; import { EventKind } from '../../shared/constants/event_kinds'; @@ -17,7 +16,7 @@ import { useIsTimelineFlyoutOpen } from '../../shared/hooks/use_is_timeline_flyo /** * Guided tour for the left panel in details flyout */ -export const LeftPanelTour: FC = memo(() => { +export const LeftPanelTour = memo(() => { const { getFieldsData, isPreview } = useLeftPanelContext(); const eventKind = getField(getFieldsData('event.kind')); const isAlert = eventKind === EventKind.signal; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx index fa8db3635be20..53d2efe883397 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx @@ -6,7 +6,7 @@ */ import { useEuiBackgroundColor } from '@elastic/eui'; -import type { VFC } from 'react'; +import type { FC } from 'react'; import React, { useMemo } from 'react'; import { css } from '@emotion/react'; import type { LeftPanelPaths } from '.'; @@ -28,7 +28,7 @@ export interface PanelContentProps { * Document details expandable flyout left section. Appears after the user clicks on the expand details button in the right section. * Displays the content of investigation and insights tabs (visualize is hidden for 8.9). */ -export const PanelContent: VFC = ({ selectedTabId, tabs }) => { +export const PanelContent: FC = ({ selectedTabId, tabs }) => { const selectedTabContent = useMemo(() => { return tabs.find((tab) => tab.id === selectedTabId)?.content; }, [selectedTabId, tabs]); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx index 308846f5dbf60..bbc8201a19f1a 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx @@ -6,7 +6,7 @@ */ import { EuiTab, EuiTabs, useEuiBackgroundColor } from '@elastic/eui'; -import type { VFC } from 'react'; +import type { FC } from 'react'; import React, { memo } from 'react'; import { css } from '@emotion/react'; import type { LeftPanelPaths } from '.'; @@ -36,7 +36,7 @@ export interface PanelHeaderProps { * Header at the top of the left section. * Displays the insights, investigation and response tabs (visualize is hidden for 8.9+). */ -export const PanelHeader: VFC = memo( +export const PanelHeader: FC = memo( ({ selectedTabId, setSelectedTabId, tabs }) => { const { getFieldsData } = useLeftPanelContext(); const isEventKindSignal = getField(getFieldsData('event.kind')) === EventKind.signal; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/insights_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/insights_tab.tsx index a60c98f46bdd2..4513e857b0b6f 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/insights_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/insights_tab.tsx @@ -84,7 +84,7 @@ const insightsButtons: EuiButtonGroupOptionProps[] = [ /** * Insights view displayed in the document details expandable flyout left section */ -export const InsightsTab: React.FC = memo(() => { +export const InsightsTab = memo(() => { const { telemetry } = useKibana().services; const { eventId, indexName, scopeId, getFieldsData } = useLeftPanelContext(); const isEventKindSignal = getField(getFieldsData('event.kind')) === EventKind.signal; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/investigation_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/investigation_tab.tsx index f52c25cf586d9..b9e7b5504cc1d 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/investigation_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/investigation_tab.tsx @@ -13,7 +13,7 @@ import { INVESTIGATION_TAB_CONTENT_TEST_ID } from './test_ids'; /** * Investigations view displayed in the document details expandable flyout left section */ -export const InvestigationTab: React.FC = memo(() => { +export const InvestigationTab = memo(() => { return ( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/response_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/response_tab.tsx index ddfe0a7f806a0..8a9de7b33b32c 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/response_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/response_tab.tsx @@ -14,7 +14,7 @@ import { RESPONSE_TAB_CONTENT_TEST_ID } from './test_ids'; /** * Response view displayed in the document details expandable flyout left section */ -export const ResponseTab: React.FC = memo(() => { +export const ResponseTab = memo(() => { return ( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/visualize_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/visualize_tab.tsx index 22a5e52c1d4a0..ab148fd04c65b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/visualize_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/tabs/visualize_tab.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useState, useCallback, useEffect } from 'react'; import { EuiButtonGroup, EuiSpacer } from '@elastic/eui'; import type { EuiButtonGroupOptionProps } from '@elastic/eui/src/components/button/button_group/button_group'; @@ -51,7 +50,7 @@ const visualizeButtons: EuiButtonGroupOptionProps[] = [ /** * Visualize view displayed in the document details expandable flyout left section */ -export const VisualizeTab: FC = memo(() => { +export const VisualizeTab = memo(() => { const { eventId, indexName, scopeId } = useLeftPanelContext(); const { openLeftPanel } = useExpandableFlyoutApi(); const panels = useExpandableFlyoutState(); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview.tsx index 5f2ecc8f5e40e..ad4e14b430149 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview.tsx @@ -47,7 +47,7 @@ const panelViewStyle = css` /** * Rule summary on a preview panel on top of the right section of expandable flyout */ -export const RulePreview: React.FC = memo(() => { +export const RulePreview = memo(() => { const { ruleId } = usePreviewPanelContext(); const [rule, setRule] = useState(null); const { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview_footer.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview_footer.tsx index 8f98e49998b95..61cd4cc2f7c01 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview_footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/preview/components/rule_preview_footer.tsx @@ -16,7 +16,7 @@ import { useRuleDetailsLink } from '../../shared/hooks/use_rule_details_link'; /** * Footer in rule preview panel */ -export const RulePreviewFooter: React.FC = memo(() => { +export const RulePreviewFooter = memo(() => { const { ruleId } = usePreviewPanelContext(); const href = useRuleDetailsLink({ ruleId }); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/about_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/about_section.tsx index 85f263ca65ef0..a02e69f611ab0 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/about_section.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/about_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useExpandSection } from '../hooks/use_expand_section'; @@ -30,7 +29,7 @@ const KEY = 'about'; * For generic events (event.kind is event), it shows the event category description and event renderer. * For all other events, it shows the event kind description, a list of event categories and event renderer. */ -export const AboutSection: FC = memo(() => { +export const AboutSection = memo(() => { const { getFieldsData } = useRightPanelContext(); const eventKind = getField(getFieldsData('event.kind')); const eventKindInECS = eventKind && isEcsAllowedValue('event.kind', eventKind); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx index 1bebeb931be4d..8386acdba31ca 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiPanel, useEuiTheme, EuiLink } from '@elastic/eui'; import { css } from '@emotion/css'; @@ -26,7 +25,7 @@ import { FlyoutTitle } from '../../../shared/components/flyout_title'; /** * Alert details flyout right section header */ -export const AlertHeaderTitle: FC = memo(() => { +export const AlertHeaderTitle = memo(() => { const { dataFormattedForFieldBrowser, eventId, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx index 44e017d725c21..f19e3c27ee4dc 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useMemo } from 'react'; import { startCase } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; @@ -22,7 +21,7 @@ import { EVENT_CATEGORY_TO_FIELD } from '../utils/event_utils'; /** * Event details flyout right section header */ -export const EventHeaderTitle: FC = memo(() => { +export const EventHeaderTitle = memo(() => { const { dataFormattedForFieldBrowser, getFieldsData } = useRightPanelContext(); const { timestamp } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.tsx index 79bca2d23de45..831124c5539e2 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -25,7 +24,7 @@ const KEY = 'insights'; /** * Insights section under overview tab. It contains entities, threat intelligence, prevalence and correlations. */ -export const InsightsSection: FC = memo(() => { +export const InsightsSection = memo(() => { const { getFieldsData } = useRightPanelContext(); const eventKind = getField(getFieldsData('event.kind')); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/investigation_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/investigation_section.tsx index 9686f322c4fab..167db7aebc058 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/investigation_section.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/investigation_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -24,7 +23,7 @@ const KEY = 'investigation'; * Second section of the overview tab in details flyout. * It contains investigation guide (alerts only) and highlighted fields */ -export const InvestigationSection: FC = memo(() => { +export const InvestigationSection = memo(() => { const { getFieldsData } = useRightPanelContext(); const eventKind = getField(getFieldsData('event.kind')); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/response_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/response_section.tsx index 4e82f450e0e80..a95d44abafe0e 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/response_section.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/response_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useExpandSection } from '../hooks/use_expand_section'; @@ -21,7 +20,7 @@ const KEY = 'response'; /** * Most bottom section of the overview tab. It contains a summary of the response tab. */ -export const ResponseSection: FC = memo(() => { +export const ResponseSection = memo(() => { const { isPreview, getFieldsData } = useRightPanelContext(); const expanded = useExpandSection({ title: KEY, defaultValue: false }); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/risk_score.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/risk_score.tsx index 6266b349f4078..95c5310b4d992 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/risk_score.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/risk_score.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { ALERT_RISK_SCORE } from '@kbn/rule-data-utils'; @@ -16,7 +15,7 @@ import { useRightPanelContext } from '../context'; /** * Document details risk score displayed in flyout right section header */ -export const RiskScore: FC = memo(() => { +export const RiskScore = memo(() => { const { getFieldsData } = useRightPanelContext(); const fieldsData = getFieldsData(ALERT_RISK_SCORE); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview.tsx index 88cbb072a9aec..a50d2e9188c88 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview.tsx @@ -7,7 +7,7 @@ import { EuiCode, EuiIcon, EuiLink, useEuiTheme } from '@elastic/eui'; import type { ReactElement } from 'react'; -import React, { useMemo, type FC } from 'react'; +import React, { useMemo, type FC, type PropsWithChildren } from 'react'; import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useRuleDetailsLink } from '../../shared/hooks/use_rule_details_link'; @@ -19,7 +19,7 @@ import { useProcessData } from '../hooks/use_process_data'; /** * One-off helper to make sure that inline values are rendered consistently */ -const ValueContainer: FC<{ text?: ReactElement }> = ({ text, children }) => ( +const ValueContainer: FC> = ({ text, children }) => ( <> {text && ( <> diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/severity.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/severity.tsx index 31295b00c7955..275affef442de 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/severity.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/severity.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { ALERT_SEVERITY } from '@kbn/rule-data-utils'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; @@ -19,7 +18,7 @@ const isSeverity = (x: unknown): x is Severity => /** * Document details severity displayed in flyout right section header */ -export const DocumentSeverity: FC = memo(() => { +export const DocumentSeverity = memo(() => { const { getFieldsData } = useRightPanelContext(); const fieldsData = getFieldsData(ALERT_SEVERITY); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/tour.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/tour.tsx index 35a5cc1e5d379..5003139a92577 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/tour.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/tour.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useMemo, useCallback } from 'react'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useRightPanelContext } from '../context'; @@ -25,7 +24,7 @@ import { useIsTimelineFlyoutOpen } from '../../shared/hooks/use_is_timeline_flyo /** * Guided tour for the right panel in details flyout */ -export const RightPanelTour: FC = memo(() => { +export const RightPanelTour = memo(() => { const { openLeftPanel, openRightPanel } = useExpandableFlyoutApi(); const { eventId, indexName, scopeId, isPreview, getFieldsData } = useRightPanelContext(); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx index ac046117fab74..afb828ebdb4e8 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -20,7 +19,7 @@ const KEY = 'visualizations'; /** * Visualizations section in overview. It contains analyzer preview and session view preview. */ -export const VisualizationsSection: FC = memo(() => { +export const VisualizationsSection = memo(() => { const expanded = useExpandSection({ title: KEY, defaultValue: false }); return ( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx index 55240ab65265d..dbc530a4dd3f6 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { VFC } from 'react'; +import type { FC } from 'react'; import React, { useMemo } from 'react'; import { FLYOUT_BODY_TEST_ID } from './test_ids'; import type { RightPanelPaths } from '.'; @@ -27,7 +27,7 @@ export interface PanelContentProps { * Document details expandable flyout right section, that will display the content * of the overview, table and json tabs. */ -export const PanelContent: VFC = ({ selectedTabId, tabs }) => { +export const PanelContent: FC = ({ selectedTabId, tabs }) => { const selectedTabContent = useMemo(() => { return tabs.find((tab) => tab.id === selectedTabId)?.content; }, [selectedTabId, tabs]); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_process_data.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_process_data.test.tsx index ac6c628ed090e..2fa72f173265d 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_process_data.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_process_data.test.tsx @@ -7,7 +7,7 @@ import { getUserDisplayName, useProcessData } from './use_process_data'; import { renderHook } from '@testing-library/react-hooks'; -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import { RightPanelContext } from '../context'; import React from 'react'; @@ -61,7 +61,7 @@ const panelContextValue = { getFieldsData: jest.fn().mockReturnValue('test'), } as unknown as RightPanelContext; -const ProviderComponent: FC = ({ children }) => ( +const ProviderComponent: FC = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/json_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/json_tab.tsx index 47294cd67d881..54d82c33b6014 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/json_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/json_tab.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo, useEffect, useRef, useState } from 'react'; import { JsonCodeEditor } from '@kbn/unified-doc-viewer-plugin/public'; import { EuiButtonEmpty, EuiCopy, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; @@ -21,7 +20,7 @@ const FLYOUT_FOOTER_HEIGHT = 72; /** * Json view displayed in the document details expandable flyout right section */ -export const JsonTab: FC = memo(() => { +export const JsonTab = memo(() => { const { searchHit, isPreview } = useRightPanelContext(); const jsonValue = JSON.stringify(searchHit, null, 2); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/overview_tab.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/overview_tab.tsx index b6202a2568479..3eb018b50d286 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/overview_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/overview_tab.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiPanel, EuiHorizontalRule } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -18,7 +17,7 @@ import { VisualizationsSection } from '../components/visualizations_section'; /** * Overview view displayed in the document details expandable flyout right section */ -export const OverviewTab: FC = memo(() => { +export const OverviewTab = memo(() => { return ( { +export const TableTab = memo(() => { const { browserFields, dataFormattedForFieldBrowser, eventId, scopeId } = useRightPanelContext(); return ( diff --git a/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx index 2f346e70b3676..8f2fc863ad000 100644 --- a/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useMemo, useState, useCallback } from 'react'; import { EuiButtonIcon, @@ -81,7 +82,7 @@ export interface ExpandablePanelPanelProps { * The content section can display a loading spinner, an error message, or any other content. * The component can be expanded or collapsed by clicking on the chevron icon on the left of the title. */ -export const ExpandablePanel: React.FC = ({ +export const ExpandablePanel: FC> = ({ header: { title, link, iconType, headerContent }, content: { loading, error } = { loading: false, error: false }, expand: { expandable, expandedOnFirstRender } = { diff --git a/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx b/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx index a957ca2f93764..46ce68f8db4a2 100644 --- a/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo, useMemo } from 'react'; import type { CommonProps } from '@elastic/eui'; import { @@ -28,7 +28,9 @@ interface AdministrationListPageProps { headerBackComponent?: React.ReactNode; } -export const AdministrationListPage: FC = memo( +export const AdministrationListPage = memo< + PropsWithChildren +>( ({ title, subtitle, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx index b0cf62647510c..d874eccae5c4c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React from 'react'; import { ThemeProvider } from 'styled-components'; import { I18nProvider } from '@kbn/i18n-react'; @@ -27,7 +28,7 @@ describe('Fleet event filters card', () => { const renderComponent: ( stats: GetExceptionSummaryResponse ) => reactTestingLibrary.RenderResult = (stats) => { - const Wrapper: React.FC = ({ children }) => ( + const Wrapper: React.FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.tsx index ffd3c9e629ea0..4d2b9367e5a54 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { PropsWithChildren } from 'react'; import React, { memo, useCallback } from 'react'; import type { EuiBadgeProps } from '@elastic/eui'; import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; @@ -90,29 +90,33 @@ export const ExceptionItemsSummary = memo( ExceptionItemsSummary.displayName = 'ExceptionItemsSummary'; -const SummaryStat: FC<{ value: number; color?: EuiBadgeProps['color']; isSmall?: boolean }> = memo( - ({ children, value, color, isSmall = false, ...commonProps }) => { - return ( - - - {!isSmall ? ( - - {children} - - ) : null} - - {value} +const SummaryStat = memo< + PropsWithChildren<{ + value: number; + color?: EuiBadgeProps['color']; + isSmall?: boolean; + }> +>(({ children, value, color, isSmall = false, ...commonProps }) => { + return ( + + + {!isSmall ? ( + + {children} - - - ); - } -); + ) : null} + + {value} + + + + ); +}); SummaryStat.displayName = 'SummaryState'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx index f727a52260873..26aaa3656147e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx @@ -5,10 +5,11 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { useUpsellingComponent } from '../../../../../common/hooks/use_upselling'; -export const EndpointAgentTamperProtectionExtension = memo(({ children }) => { +export const EndpointAgentTamperProtectionExtension = memo(({ children }) => { const Component = useUpsellingComponent('endpoint_agent_tamper_protection'); if (!Component) { return <>{children}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx index a19bea940adfc..e90b15e760283 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { useEffect } from 'react'; import type { Action, Reducer } from 'redux'; import type { RenderOptions } from '@testing-library/react'; @@ -82,7 +83,7 @@ export const createFleetContextRendererMock = (): AppContextTestRender => { additionalMiddleware: [mockedContext.middlewareSpy.actionSpyMiddleware], }); - const Wrapper: RenderOptions['wrapper'] = ({ children }) => { + const Wrapper: RenderOptions['wrapper'] = ({ children }: PropsWithChildren) => { useEffect(() => { return () => { // When the component un-mounts, reset the Experimental features since diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx index e364e92fe9218..bf29bef12d94a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx @@ -110,7 +110,7 @@ export const PolicySettingsForm = memo((props) => { }); PolicySettingsForm.displayName = 'PolicySettingsForm'; -const FormSectionTitle = memo(({ children }) => { +const FormSectionTitle = memo(({ children }) => { return (

    {children}

    diff --git a/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx index 6c2624e4b6966..e9252405fbb0f 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx @@ -9,13 +9,14 @@ import { render } from '@testing-library/react'; import { LandingPage } from './landing'; import { Router } from '@kbn/shared-ux-router'; import { createBrowserHistory } from 'history'; +import type { PropsWithChildren } from 'react'; import React from 'react'; jest.mock('../../common/components/landing_page'); jest.mock('../../common/components/page_wrapper', () => ({ SecuritySolutionPageWrapper: jest .fn() - .mockImplementation(({ children }) =>
    {children}
    ), + .mockImplementation(({ children }: PropsWithChildren) =>
    {children}
    ), })); const history = createBrowserHistory(); describe('LandingPage', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx index d95bd56182848..efe693abe24ad 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx @@ -75,7 +75,7 @@ interface Props { const emptyNotes: string[] = []; -const EventsTrSupplementContainerWrapper = React.memo(({ children }) => { +const EventsTrSupplementContainerWrapper = React.memo(({ children }) => { const width = useEventDetailsWidthContext(); return {children}; }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_badge.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_badge.tsx index 7934f1a0443ae..eccfb1b3eec77 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_badge.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_badge.tsx @@ -201,7 +201,7 @@ export const ProviderBadge = React.memo( {content} - {/* Add a UI feature to let users know the is one of operator doesnt work with timeline templates: + {/* Add a UI feature to let users know the is one of operator doesnt work with timeline templates: https://github.com/elastic/kibana/issues/142437 */} {timelineType === TimelineType.template && operator !== IS_ONE_OF_OPERATOR && ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx index 8d43b8b785eff..0da2d6ca7bd88 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx @@ -7,7 +7,7 @@ import type { EuiContextMenuPanelDescriptor, EuiPopoverProps } from '@elastic/eui'; import { EuiContextMenu, EuiPopover } from '@elastic/eui'; -import type { FunctionComponent } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import styled from 'styled-components'; @@ -53,10 +53,11 @@ interface OwnProps { type: DataProviderType; } -const MyEuiPopover = styled(EuiPopover as unknown as FunctionComponent)< - EuiPopoverProps & { - id?: string; - } +const MyEuiPopover = styled(EuiPopover as unknown as FC)< + EuiPopoverProps & + PropsWithChildren<{ + id?: string; + }> >` height: 100%; user-select: none; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx index fa643a2e03ea0..7168588bb9599 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { render } from '@testing-library/react'; @@ -84,7 +85,7 @@ describe('useSessionView with active timeline and a session id and graph event i let setTimelineFullScreen: jest.Mock; let setGlobalFullScreen: jest.Mock; let kibana: ReturnType; - const Wrapper = memo(({ children }) => { + const Wrapper = memo(({ children }) => { kibana = useKibana(); return {children}; }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx index 291a2bfa4d6e6..e7688e9a7db95 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { ComponentProps } from 'react'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; import React, { useEffect } from 'react'; import type QueryTabContent from '.'; import { UnifiedTimeline } from '.'; @@ -136,7 +136,7 @@ const TestComponent = (props: Partial>) = const customStore = createMockStore(); -const TestProviderWrapperWithCustomStore: React.FC = ({ children }) => { +const TestProviderWrapperWithCustomStore: FC = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/security_solution_ess/public/common/services.tsx b/x-pack/plugins/security_solution_ess/public/common/services.tsx index 106782e337cc0..42605eea525d9 100644 --- a/x-pack/plugins/security_solution_ess/public/common/services.tsx +++ b/x-pack/plugins/security_solution_ess/public/common/services.tsx @@ -6,6 +6,7 @@ */ import type { CoreStart } from '@kbn/core/public'; +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { KibanaContextProvider, @@ -16,9 +17,11 @@ import type { SecuritySolutionEssPluginStartDeps } from '../types'; export type Services = CoreStart & SecuritySolutionEssPluginStartDeps; -export const KibanaServicesProvider: React.FC<{ - services: Services; -}> = ({ services, children }) => { +export const KibanaServicesProvider: FC< + PropsWithChildren<{ + services: Services; + }> +> = ({ services, children }) => { return ( {children} diff --git a/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx b/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx index 7d7dd9d75e8c3..100295a717464 100644 --- a/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx @@ -5,13 +5,14 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { mockServices } from './services.mock'; import { NavigationProvider } from '@kbn/security-solution-navigation'; -export const ServicesProvider: React.FC = ({ children }) => ( +export const ServicesProvider: FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/security_solution_serverless/public/common/services/services.tsx b/x-pack/plugins/security_solution_serverless/public/common/services/services.tsx index 41097b1ea470f..72d2ff67dd5f4 100644 --- a/x-pack/plugins/security_solution_serverless/public/common/services/services.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/services/services.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren, FC } from 'react'; import React from 'react'; import { KibanaContextProvider, @@ -13,9 +14,11 @@ import { import { NavigationProvider } from '@kbn/security-solution-navigation'; import type { Services } from './types'; -export const ServicesProvider: React.FC<{ - services: Services; -}> = ({ services, children }) => { +export const ServicesProvider: FC< + PropsWithChildren<{ + services: Services; + }> +> = ({ services, children }) => { return ( {children} diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx index 8b2b54e17d68e..924bce20ffbac 100644 --- a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx @@ -13,7 +13,7 @@ export interface IndexOverviewPanelProps { footer?: React.ReactNode | React.ReactNode[]; } -export const IndexOverviewPanel: React.FC = ({ +export const IndexOverviewPanel: FC> = ({ title, footer, children, @@ -34,7 +34,7 @@ export const IndexOverviewPanel: React.FC = ({ ); -export const IndexOverviewPanelStat: React.FC = ({ children }) => ( +export const IndexOverviewPanelStat: FC = ({ children }) => (

    {children}

    diff --git a/x-pack/plugins/serverless_search/public/application/components/overview.tsx b/x-pack/plugins/serverless_search/public/application/components/overview.tsx index 6607607ad0c84..4fbef0277222a 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview.tsx @@ -30,7 +30,7 @@ import { getConsoleRequest, } from '@kbn/search-api-panels'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState, FC, PropsWithChildren } from 'react'; import type { LanguageDefinition, LanguageDefinitionSnippetArguments, @@ -484,7 +484,7 @@ const OverviewFooter = () => { ); }; -const FooterButtonContainer: React.FC = ({ children }) => ( +const FooterButtonContainer: FC = ({ children }) => ( diff --git a/x-pack/plugins/serverless_search/public/test/test_utils.tsx b/x-pack/plugins/serverless_search/public/test/test_utils.tsx index 1012528cd3b36..01cba69d3cc08 100644 --- a/x-pack/plugins/serverless_search/public/test/test_utils.tsx +++ b/x-pack/plugins/serverless_search/public/test/test_utils.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { ReactElement } from 'react'; +import React, { ReactElement, FC, PropsWithChildren } from 'react'; import { render, RenderOptions } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; @@ -32,7 +32,7 @@ const queryClient = new QueryClient({ }, }); -const AllTheProviders: React.FC = ({ children }) => { +const AllTheProviders: FC = ({ children }) => { return ( diff --git a/x-pack/plugins/spaces/public/spaces_context/context.tsx b/x-pack/plugins/spaces/public/spaces_context/context.tsx index 69df4a639ca91..5fe227c37e43c 100644 --- a/x-pack/plugins/spaces/public/spaces_context/context.tsx +++ b/x-pack/plugins/spaces/public/spaces_context/context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import * as React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import type { CoreStart } from '@kbn/core/public'; @@ -32,7 +32,7 @@ export const createSpacesReactContext = >( spacesDataPromise, services, }; - const Provider: React.FC = ({ children }) => + const Provider: FC = ({ children }) => createElement(context.Provider as React.ComponentType, { value, children }); return { diff --git a/x-pack/plugins/spaces/public/spaces_context/types.ts b/x-pack/plugins/spaces/public/spaces_context/types.ts index 1ca0985c1b62d..0cac358333f88 100644 --- a/x-pack/plugins/spaces/public/spaces_context/types.ts +++ b/x-pack/plugins/spaces/public/spaces_context/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type * as React from 'react'; +import type React from 'react'; import type { CoreStart, StartServicesAccessor } from '@kbn/core/public'; @@ -21,7 +21,7 @@ export interface SpacesReactContextValue> { export interface SpacesReactContext> { value: SpacesReactContextValue; - Provider: React.FC; + Provider: React.FC; Consumer: React.Consumer>; } @@ -38,4 +38,5 @@ export interface SpacesContextProps { * If a feature is specified, all Spaces components will treat it appropriately if the feature is disabled in a given Space. */ feature?: string; + children?: React.ReactNode; } diff --git a/x-pack/plugins/spaces/public/spaces_context/wrapper.tsx b/x-pack/plugins/spaces/public/spaces_context/wrapper.tsx index 8fae6e78d1bb2..4b45498a04cc7 100644 --- a/x-pack/plugins/spaces/public/spaces_context/wrapper.tsx +++ b/x-pack/plugins/spaces/public/spaces_context/wrapper.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { PropsWithChildren } from 'react'; import React from 'react'; import type { InternalProps, SpacesContextProps } from './types'; @@ -14,7 +13,7 @@ export const getSpacesContextProviderWrapper = async ( internalProps: InternalProps ): Promise> => { const { SpacesContextWrapperInternal } = await import('./wrapper_internal'); - return ({ children, ...props }: PropsWithChildren) => { + return ({ children, ...props }: SpacesContextProps) => { return ; }; }; diff --git a/x-pack/plugins/spaces/public/ui_api/components.tsx b/x-pack/plugins/spaces/public/ui_api/components.tsx index abf9e8c0ecd1c..7138432bbff8a 100644 --- a/x-pack/plugins/spaces/public/ui_api/components.tsx +++ b/x-pack/plugins/spaces/public/ui_api/components.tsx @@ -33,7 +33,10 @@ export const getComponents = ({ /** * Returns a function that creates a lazy-loading version of a component. */ - function wrapLazy(fn: () => Promise>, options: { showLoadingSpinner?: boolean } = {}) { + function wrapLazy( + fn: () => Promise>>, + options: { showLoadingSpinner?: boolean } = {} + ) { const { showLoadingSpinner } = options; return (props: JSX.IntrinsicAttributes & PropsWithRef>) => ( { - fn: () => Promise>; + fn: () => Promise>>; getStartServices: StartServicesAccessor; showLoadingSpinner?: boolean; props: JSX.IntrinsicAttributes & PropsWithRef>; diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx index aed0f36b27c8e..b4457e55eda8a 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { cleanup, render, screen, waitFor } from '@testing-library/react'; import { I18nProvider } from '@kbn/i18n-react'; import { SourceFields } from './source_fields_select'; import { SourceField } from '../es_query/types'; -const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( +const AppWrapper = React.memo(({ children }) => ( {children} )); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx index 025ac9deac732..99af4c482f976 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { fireEvent, render, waitFor } from '@testing-library/react'; import { I18nProvider } from '@kbn/i18n-react'; @@ -27,7 +27,7 @@ jest.mock('@kbn/text-based-editor', () => ({ const { fetchFieldsFromESQL } = jest.requireMock('@kbn/text-based-editor'); const { getFields } = jest.requireMock('@kbn/triggers-actions-ui-plugin/public'); -const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( +const AppWrapper = React.memo(({ children }) => ( {children} )); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx index 3cd4172a94035..6fad9c97abcfe 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import React from 'react'; +import React, { PropsWithChildren } from 'react'; import { render } from '@testing-library/react'; import { I18nProvider } from '@kbn/i18n-react'; import { TestQueryRowTable } from './test_query_row_table'; -const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( +const AppWrapper = React.memo(({ children }) => ( {children} )); diff --git a/x-pack/plugins/threat_intelligence/public/components/layout.tsx b/x-pack/plugins/threat_intelligence/public/components/layout.tsx index ececea8ac6e34..0f7c916c77feb 100644 --- a/x-pack/plugins/threat_intelligence/public/components/layout.tsx +++ b/x-pack/plugins/threat_intelligence/public/components/layout.tsx @@ -6,7 +6,7 @@ */ import { EuiPageHeader, EuiPageHeaderSection, EuiSpacer, EuiText } from '@elastic/eui'; -import React, { FC, ReactNode } from 'react'; +import React, { FC, PropsWithChildren, ReactNode } from 'react'; import { SecuritySolutionPageWrapper } from '../containers/security_solution_page_wrapper'; import { TITLE_TEST_ID } from './test_ids'; @@ -16,7 +16,7 @@ export interface LayoutProps { subHeader?: ReactNode; } -export const DefaultPageLayout: FC = ({ +export const DefaultPageLayout: FC> = ({ children, pageTitle, border = true, diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx index 8f9995050eeb1..f396d6ae4711f 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React, { FC, memo } from 'react'; +import React, { memo, PropsWithChildren } from 'react'; import { Paywall } from '../components/paywall'; import { useSecurityContext } from '../hooks/use_security_context'; import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugin_template_wrapper'; -export const EnterpriseGuard: FC = memo(({ children }) => { +export const EnterpriseGuard = memo(({ children }) => { const { licenseService } = useSecurityContext(); if (licenseService.isEnterprise()) { diff --git a/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx b/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx index 027236194e7ce..ba12aafa51d27 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { createContext, FC, useMemo } from 'react'; +import React, { createContext, FC, PropsWithChildren, useMemo } from 'react'; import { useSourcererDataView } from '../modules/indicators/hooks/use_sourcerer_data_view'; export type FieldTypesContextValue = Record; @@ -15,7 +15,7 @@ export const FieldTypesContext = createContext { +export const FieldTypesProvider: FC = ({ children }) => { const { indexPattern } = useSourcererDataView(); // field name to field type map to allow the cell_renderer to format dates diff --git a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx index efe273feeedfe..106f8c367844c 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useSecurityContext } from '../hooks/use_security_context'; -export const FiltersGlobal: FC = ({ children }) => { +export const FiltersGlobal: FC = ({ children }) => { const contextValue = useSecurityContext(); const Component = contextValue.getFiltersGlobalComponent(); diff --git a/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx b/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx index 622fa2df24640..836b9a650fd78 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx @@ -6,7 +6,7 @@ */ import { RequestAdapter } from '@kbn/inspector-plugin/common'; -import React, { createContext, FC, useMemo } from 'react'; +import React, { createContext, FC, PropsWithChildren, useMemo } from 'react'; export interface InspectorContextValue { requests: RequestAdapter; @@ -14,7 +14,7 @@ export interface InspectorContextValue { export const InspectorContext = createContext(undefined); -export const InspectorProvider: FC = ({ children }) => { +export const InspectorProvider: FC = ({ children }) => { const inspectorAdapters = useMemo(() => ({ requests: new RequestAdapter() }), []); return ( diff --git a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx index aac955e2434de..c7c2c93e5e23a 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx @@ -6,7 +6,7 @@ */ import { EuiLoadingLogo, EuiPageTemplate } from '@elastic/eui'; -import React, { FC, memo } from 'react'; +import React, { memo, PropsWithChildren } from 'react'; import { LOADING_LOGO_TEST_ID } from './test_ids'; import { useIntegrations } from '../hooks/use_integrations'; import { EmptyPage } from '../modules/empty_page/empty_page'; @@ -19,7 +19,7 @@ import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugi * If none are received, show the EmptyPage with a link to go install integrations. * While the indicators call and the integrations call are loading, display a loading screen. */ -export const IntegrationsGuard: FC = memo(({ children }) => { +export const IntegrationsGuard = memo(({ children }) => { const { isLoading: indicatorsTotalCountLoading, count: indicatorsTotalCount } = useIndicatorsTotalCount(); diff --git a/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx b/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx index a663795f3b521..167f4bbbfeed6 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { useSecurityContext } from '../hooks/use_security_context'; /** * Security solution page wrapper, with some extra styling etc. */ -export const SecuritySolutionPageWrapper: FC = ({ children }) => { +export const SecuritySolutionPageWrapper: FC = ({ children }) => { const contextValue = useSecurityContext(); const Component = contextValue.getPageWrapper(); diff --git a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx index 967e21642dd24..6dd93abb6ccba 100644 --- a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx @@ -6,7 +6,7 @@ */ import moment from 'moment/moment'; -import React, { FC } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { BehaviorSubject } from 'rxjs'; import { I18nProvider } from '@kbn/i18n-react'; import { coreMock } from '@kbn/core/public/mocks'; @@ -138,7 +138,7 @@ export const mockedServices = { }, }; -export const TestProvidersComponent: FC = ({ children }) => ( +export const TestProvidersComponent: FC = ({ children }) => ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx index 3bdd3be858af7..2fcbbdbd9795a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx @@ -5,7 +5,14 @@ * 2.0. */ -import React, { createContext, Dispatch, FC, SetStateAction, useState } from 'react'; +import React, { + createContext, + Dispatch, + FC, + PropsWithChildren, + SetStateAction, + useState, +} from 'react'; export interface BlockListContextValue { blockListIndicatorValue: string; @@ -14,7 +21,7 @@ export interface BlockListContextValue { export const BlockListContext = createContext(undefined); -export const BlockListProvider: FC = ({ children }) => { +export const BlockListProvider: FC = ({ children }) => { const [blockListIndicatorValue, setBlockListIndicatorValue] = useState(''); const context: BlockListContextValue = { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx index eb2897f290bb9..43ebe7d510f54 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, useMemo } from 'react'; +import React, { FC, useMemo, PropsWithChildren } from 'react'; import { useKibana } from '../../../hooks/use_kibana'; import { useSecurityContext } from '../../../hooks/use_security_context'; import { @@ -16,7 +16,7 @@ import { /** * Container used to wrap components and share the {@link FilterManager} through React context. */ -export const IndicatorsFilters: FC = ({ children }) => { +export const IndicatorsFilters: FC = ({ children }) => { const securityContext = useSecurityContext(); const { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx index 4edbb8e22f7d6..4f7b65864d96f 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, VFC } from 'react'; +import React, { FC, VFC, PropsWithChildren } from 'react'; import { useBlockListContext } from '../hooks/use_block_list_context'; import { BlockListProvider } from '../containers/block_list_provider'; import { BlockListFlyout } from '../../block_list/containers/flyout'; @@ -24,7 +24,7 @@ import { IndicatorsFilters } from '../containers/filters'; import { UpdateStatus } from '../../../components/update_status'; import { QueryBar } from '../../query_bar/components/query_bar'; -const IndicatorsPageProviders: FC = ({ children }) => ( +const IndicatorsPageProviders: FC = ({ children }) => ( diff --git a/x-pack/plugins/transform/public/app/components/capabilities_wrapper.tsx b/x-pack/plugins/transform/public/app/components/capabilities_wrapper.tsx index ce850aa2ffc6c..d5fa33c88369d 100644 --- a/x-pack/plugins/transform/public/app/components/capabilities_wrapper.tsx +++ b/x-pack/plugins/transform/public/app/components/capabilities_wrapper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiPageTemplate, EuiEmptyPrompt } from '@elastic/eui'; @@ -48,9 +48,11 @@ const MissingCapabilities: FC = () => ( ); -export const CapabilitiesWrapper: FC<{ - requiredCapabilities: TransformCapability | TransformCapability[]; -}> = ({ children, requiredCapabilities }) => { +export const CapabilitiesWrapper: FC< + PropsWithChildren<{ + requiredCapabilities: TransformCapability | TransformCapability[]; + }> +> = ({ children, requiredCapabilities }) => { const capabilities = useTransformCapabilities(); const hasCapabilities = toArray(requiredCapabilities).every((c) => capabilities[c]); 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 6e5b360119de8..902a98fe58549 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 @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import '@testing-library/jest-dom/extend-expect'; import { render, screen, waitFor } from '@testing-library/react'; @@ -48,7 +48,7 @@ const queryClient = new QueryClient(); describe('Transform: useIndexData()', () => { test('dataView set triggers loading', async () => { const mlShared = await getMlSharedImports(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx b/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx index 67f1a49e6ec64..80bbdeb2bb601 100644 --- a/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { act, renderHook } from '@testing-library/react-hooks'; import { getTransformConfigMock } from './__mocks__/transform_config'; @@ -21,7 +21,7 @@ import { useIsFormValid } from './selectors/is_form_valid'; describe('Transform: useEditTransformFlyoutActions/Selector()', () => { it('field updates should trigger form validation', () => { const transformConfigMock = getTransformConfigMock(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx index 34b69e45f087a..ac8eeb9ebce71 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook } from '@testing-library/react-hooks'; @@ -17,7 +17,7 @@ import { useActions } from './use_actions'; describe('Transform: Transform List Actions', () => { test('useActions()', async () => { const queryClient = new QueryClient(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); const { result, waitForNextUpdate } = renderHook( diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx index e49df35b42a55..b6b6636e91f38 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { type FC } from 'react'; +import React, { type FC, type PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook } from '@testing-library/react-hooks'; @@ -17,7 +17,7 @@ jest.mock('../../../../app_dependencies'); describe('Transform: Job List Columns', () => { test('useColumns()', async () => { const queryClient = new QueryClient(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC = ({ children }) => ( {children} ); const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, [], false), { diff --git a/x-pack/plugins/transform/public/app/serverless_context.tsx b/x-pack/plugins/transform/public/app/serverless_context.tsx index 108eea3a7016c..9faa5e0946be1 100644 --- a/x-pack/plugins/transform/public/app/serverless_context.tsx +++ b/x-pack/plugins/transform/public/app/serverless_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import React, { createContext, useContext, useMemo } from 'react'; import type { ExperimentalFeatures } from '../../common/config'; @@ -16,9 +16,11 @@ export const EnabledFeaturesContext = createContext({ showNodeInfo: true, }); -export const EnabledFeaturesContextProvider: FC<{ - enabledFeatures: TransformEnabledFeatures; -}> = (props) => { +export const EnabledFeaturesContextProvider: FC< + PropsWithChildren<{ + enabledFeatures: TransformEnabledFeatures; + }> +> = (props) => { const { children, enabledFeatures } = props; return ( @@ -30,9 +32,11 @@ export const EnabledFeaturesContextProvider: FC<{ export const ExperimentalFeaturesContext = createContext({ ruleFormV2Enabled: false, }); -export const ExperimentalFeaturesContextProvider: FC<{ - experimentalFeatures: ExperimentalFeatures; -}> = (props) => { +export const ExperimentalFeaturesContextProvider: FC< + PropsWithChildren<{ + experimentalFeatures: ExperimentalFeatures; + }> +> = (props) => { const { children, experimentalFeatures } = props; return ( diff --git a/x-pack/plugins/triggers_actions_ui/.storybook/decorator.tsx b/x-pack/plugins/triggers_actions_ui/.storybook/decorator.tsx index 68df880a1b6b5..183b1acd3ca53 100644 --- a/x-pack/plugins/triggers_actions_ui/.storybook/decorator.tsx +++ b/x-pack/plugins/triggers_actions_ui/.storybook/decorator.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { action } from '@storybook/addon-actions'; import { DecoratorFn } from '@storybook/react'; @@ -50,7 +50,9 @@ const notifications: NotificationsStart = { showErrorDialog: () => {}, }; -export const StorybookContextDecorator: React.FC = (props) => { +export const StorybookContextDecorator: FC> = ( + props +) => { const { children, context, servicesApplicationOverride, servicesOverride } = props; const { globals } = context; const { euiTheme } = globals; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx index c274bee5eb865..909b347b38289 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { Option, none, some, fold, isSome } from 'fp-ts/lib/Option'; import { pipe } from 'fp-ts/lib/pipeable'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -34,7 +34,7 @@ interface HealthStatus { hasPermanentEncryptionKey: boolean; } -export const HealthCheck: React.FunctionComponent = ({ +export const HealthCheck: FC> = ({ children, waitForCheck, inFlyout = false, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx index 76149e7eef70a..9a98adc0f48d9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import React, { useState, useCallback } from 'react'; +import React, { useState, useCallback, FC, PropsWithChildren } from 'react'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; const seeFullErrorMessage = i18n.translate( @@ -23,7 +23,7 @@ const hideFullErrorMessage = i18n.translate( } ); -export const ToastWithCircuitBreakerContent: React.FC = ({ children }) => { +export const ToastWithCircuitBreakerContent: FC = ({ children }) => { const [showDetails, setShowDetails] = useState(false); const onToggleShowDetails = useCallback(() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/connector_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/connector_context.tsx index e97cf789936ae..379e75bee8f20 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/connector_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/connector_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { ConnectorServices } from '../../types'; export interface ConnectorContextValue { @@ -14,10 +14,11 @@ export interface ConnectorContextValue { export const ConnectorContext = React.createContext(undefined); -export const ConnectorProvider: React.FC<{ value: ConnectorContextValue }> = ({ - children, - value, -}) => { +export const ConnectorProvider: FC< + PropsWithChildren<{ + value: ConnectorContextValue; + }> +> = ({ children, value }) => { return {children}; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx index 13cf44b052b7a..eb51ecde8cbaa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { QueryClient, QueryClientProvider, QueryClientProviderProps } from '@tanstack/react-query'; // FIXME: adds inefficient boilerplate that should not be required. See https://github.com/elastic/kibana/issues/180725 import { I18nProvider } from '@kbn/i18n-react'; @@ -25,7 +25,7 @@ export interface AppMockRenderer { render: UiRender; coreStart: TriggersAndActionsUiServices; queryClient: QueryClient; - AppWrapper: React.FC<{ children: React.ReactElement }>; + AppWrapper: FC; } export const createAppMockRenderer = ( @@ -51,7 +51,7 @@ export const createAppMockRenderer = ( }, }); - const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( + const AppWrapper = React.memo(({ children }) => ( diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx index 9a53d1324279c..c9dbe72e142e0 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import React, { FunctionComponent } from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiIcon } from '@elastic/eui'; -export const LoadingIssuesError: FunctionComponent = ({ children }) => ( +export const LoadingIssuesError: FC = ({ children }) => ( From 3e7f11b349e19e72e12dc02e3d97e6aa528b03b7 Mon Sep 17 00:00:00 2001 From: Trevor Pierce <1Copenut@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:01:45 -0500 Subject: [PATCH 002/104] [TASK][Security Serverless]: Add semantic headings to Get Started page (#181494) Refactored the Security Serverless "Getting Started" page to use semantic headings instead of P and SPAN tags marked up as headings. --- .../landing_page/onboarding/footer/index.tsx | 6 ++++-- .../onboarding/hooks/use_setup_sections.tsx | 4 ++-- .../onboarding/step_links/add_integration_buttons.tsx | 6 ++++-- .../onboarding/styles/step_content.styles.ts | 10 +++++++++- .../landing_page/onboarding/welcome_header/index.tsx | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/footer/index.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/footer/index.tsx index 9d026f12b4925..1dd0839e5b758 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/footer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/footer/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer, EuiTitle } from '@elastic/eui'; import React, { useMemo } from 'react'; import { useFooterStyles } from '../styles/footer.styles'; @@ -25,7 +25,9 @@ const FooterComponent = () => { {item.title} -

    {item.title}

    + +

    {item.title}

    +

    {item.description}

    diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/hooks/use_setup_sections.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/hooks/use_setup_sections.tsx index 295d6565a4cf1..7587f065a4de9 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/hooks/use_setup_sections.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/hooks/use_setup_sections.tsx @@ -101,14 +101,14 @@ export const useSetUpSections = ({ euiTheme }: { euiTheme: EuiThemeComputed }) = id={currentSection.id} data-test-subj={`section-${currentSection.id}`} > - {currentSection.title} - +
    -

    {title}

    + +

    {title}

    +
    {description} diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/styles/step_content.styles.ts b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/styles/step_content.styles.ts index 8cd3026000dc4..c0ab2961e4f4b 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/styles/step_content.styles.ts +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/styles/step_content.styles.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useEuiShadow, useEuiTheme } from '@elastic/eui'; +import { useEuiShadow, useEuiTheme, useEuiFontSize } from '@elastic/eui'; import { css } from '@emotion/css'; import { useMemo } from 'react'; @@ -16,6 +16,7 @@ export const RIGHT_CONTENT_WIDTH = 513; export const useStepContentStyles = () => { const { euiTheme } = useEuiTheme(); const imageShadow = useEuiShadow('s'); + const descriptionHeader = useEuiFontSize('s'); const customStyles = useMemo( () => ({ @@ -45,6 +46,11 @@ export const useStepContentStyles = () => { '.step-paragraph': { marginTop: euiTheme.size.xl, }, + + '.euiTitle': { + fontSize: `${descriptionHeader.fontSize}`, + lineHeight: `${descriptionHeader.lineHeight}`, + }, }, }), rightPanelStyles: css({ @@ -77,6 +83,8 @@ export const useStepContentStyles = () => { euiTheme.size.s, euiTheme.size.xl, imageShadow, + descriptionHeader.fontSize, + descriptionHeader.lineHeight, ] ); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/welcome_header/index.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/welcome_header/index.tsx index c4d5fa13ec6f6..848eece5b243a 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/welcome_header/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/welcome_header/index.tsx @@ -52,7 +52,7 @@ const WelcomeHeaderComponent: React.FC<{ productTier?: ProductTier }> = ({ produ )} - {GET_STARTED_PAGE_SUBTITLE} +

    {GET_STARTED_PAGE_SUBTITLE}

    {GET_STARTED_PAGE_DESCRIPTION} From 0b6f1e41633c977f31f9b8659fdbb022b00e101e Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Mon, 29 Apr 2024 12:42:48 -0400 Subject: [PATCH 003/104] [Security Solution] [Detections] Detect and mitigate maxClauseCount errors during query phase of indicator match rules (#179748) ## Summary Ref: https://github.com/elastic/security-team/issues/7803 This PR implements the suggested idea found [here](https://github.com/elastic/security-team/issues/7803#issuecomment-1789276731) under the heading **More immediate solution**. This solution is still susceptible to the timeout issues described in that comment due to the rule taking longer to complete execution, but it stops the harder-to-control error related to max clause count. --- .../create_security_rule_type_wrapper.ts | 2 +- .../indicator_match/indicator_match.ts | 3 +- .../threat_mapping/create_event_signal.ts | 38 ++++- .../threat_mapping/create_threat_signals.ts | 96 ++++++++++--- .../threat_mapping/utils.test.ts | 133 ++++++++++++++++++ .../indicator_match/threat_mapping/utils.ts | 85 ++++++++++- .../utils/search_after_bulk_create_factory.ts | 1 - 7 files changed, 327 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index 644dff4ec761e..34a0d7f198e22 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -464,7 +464,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = if (result.warningMessages.length) { await ruleExecutionLogger.logStatusChange({ newStatus: RuleExecutionStatusEnum['partial failure'], - message: truncateList(result.warningMessages).join(), + message: truncateList(result.warningMessages).join(', '), metrics: { searchDurations: result.searchAfterTimes, indexingDurations: result.bulkCreateTimes, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/indicator_match.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/indicator_match.ts index 7423abe73a51d..4f004f0bdc628 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/indicator_match.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/indicator_match.ts @@ -23,6 +23,7 @@ import type { CompleteRule, ThreatRuleParams } from '../../rule_schema'; import { withSecuritySpan } from '../../../../utils/with_security_span'; import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../common/constants'; import type { IRuleExecutionLogForExecutors } from '../../rule_monitoring'; +import { MAX_PER_PAGE } from './threat_mapping/get_event_count'; import type { ExperimentalFeatures } from '../../../../../common'; export const indicatorMatchExecutor = async ({ @@ -81,7 +82,7 @@ export const indicatorMatchExecutor = async ({ eventsTelemetry, filters: ruleParams.filters ?? [], inputIndex, - itemsPerSearch: ruleParams.itemsPerSearch ?? 9000, + itemsPerSearch: ruleParams.itemsPerSearch ?? MAX_PER_PAGE, language: ruleParams.language, listClient, outputIndex: ruleParams.outputIndex, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts index 8782f34e0afdc..e6bd194504fd6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts @@ -15,7 +15,11 @@ import { getSignalsQueryMapFromThreatIndex } from './get_signals_map_from_threat import { searchAfterAndBulkCreateSuppressedAlerts } from '../../utils/search_after_bulk_create_suppressed_alerts'; import { threatEnrichmentFactory } from './threat_enrichment_factory'; -import { getSignalValueMap } from './utils'; +import { + FAILED_CREATE_QUERY_MAX_CLAUSE, + getSignalValueMap, + MANY_NESTED_CLAUSES_ERR, +} from './utils'; export const createEventSignal = async ({ bulkCreate, @@ -92,12 +96,32 @@ export const createEventSignal = async ({ indexFields: threatIndexFields, }; - const signalsQueryMap = await getSignalsQueryMapFromThreatIndex({ - threatSearchParams, - eventsCount: currentEventList.length, - signalValueMap: getSignalValueMap({ eventList: currentEventList, threatMatchedFields }), - termsQueryAllowed: true, - }); + let signalsQueryMap; + try { + signalsQueryMap = await getSignalsQueryMapFromThreatIndex({ + threatSearchParams, + eventsCount: currentEventList.length, + signalValueMap: getSignalValueMap({ + eventList: currentEventList, + threatMatchedFields, + }), + termsQueryAllowed: true, + }); + } catch (exc) { + // we receive an error if the event list count < threat list count + // which puts us into the create_event_signal which differs from create threat signal + // in that we call getSignalsQueryMapFromThreatIndex which can *throw* an error + // rather than *return* one. + if ( + exc.message.includes(MANY_NESTED_CLAUSES_ERR) || + exc.message.includes(FAILED_CREATE_QUERY_MAX_CLAUSE) + ) { + currentResult.errors.push(exc.message); + return currentResult; + } else { + throw exc; + } + } const ids = Array.from(signalsQueryMap.keys()); const indexFilter = { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index 1dc4d92b44ab9..08460473eaf4b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -10,6 +10,8 @@ import { firstValueFrom } from 'rxjs'; import type { OpenPointInTimeResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { uniq, chunk } from 'lodash/fp'; + +import { TelemetryChannel } from '../../../../telemetry/types'; import { getThreatList, getThreatListCount } from './get_threat_list'; import type { CreateThreatSignalsOptions, @@ -23,7 +25,10 @@ import { MAX_SIGNALS_SUPPRESSION_MULTIPLIER } from '../../constants'; import { buildExecutionIntervalValidator, combineConcurrentResults, + FAILED_CREATE_QUERY_MAX_CLAUSE, getMatchedFields, + getMaxClauseCountErrorValue, + MANY_NESTED_CLAUSES_ERR, } from './utils'; import { getAllowedFieldsForTermQuery } from './get_allowed_fields_for_terms_query'; @@ -71,6 +76,7 @@ export const createThreatSignals = async ({ experimentalFeatures, }: CreateThreatSignalsOptions): Promise => { const threatMatchedFields = getMatchedFields(threatMapping); + const threatFieldsLength = threatMatchedFields.threat.length; const allowedFieldsForTermsQuery = await getAllowedFieldsForTermQuery({ services, threatMatchedFields, @@ -170,14 +176,57 @@ export const createThreatSignals = async ({ let list = await getDocumentList({ searchAfter: undefined }); let documentCount = totalDocumentCount; + // this is re-assigned depending on max clause count errors + let chunkPage = itemsPerSearch; + while (list.hits.hits.length !== 0) { verifyExecutionCanProceed(); - const chunks = chunk(itemsPerSearch, list.hits.hits); + const chunks = chunk(chunkPage, list.hits.hits); ruleExecutionLogger.debug(`${chunks.length} concurrent indicator searches are starting.`); const concurrentSearchesPerformed = chunks.map>(createSignal); const searchesPerformed = await Promise.all(concurrentSearchesPerformed); - results = combineConcurrentResults(results, searchesPerformed); + + const { maxClauseCountValue, errorType } = getMaxClauseCountErrorValue( + searchesPerformed, + threatFieldsLength, + chunkPage, + eventsTelemetry + ); + + if (maxClauseCountValue > Number.NEGATIVE_INFINITY) { + eventsTelemetry?.sendAsync(TelemetryChannel.DETECTION_ALERTS, [ + `indicator match with rule id: ${alertId} generated a max clause count error, attempting to resolve within executor. Setting IM rule page size to ${maxClauseCountValue}`, + ]); + // parse the error message to acquire the number of maximum possible clauses + // allowed by elasticsearch. The sliced chunk is used in createSignal to generate + // threat filters. + chunkPage = maxClauseCountValue; + ruleExecutionLogger.warn( + `maxClauseCount error received from elasticsearch, setting IM rule page size to ${maxClauseCountValue}` + ); + + // only store results + errors that are not related to maxClauseCount + // since the maxClauseCount error is not relevant since we will be re-running + // the createSignal loop with the updated chunk sizes. + results = combineConcurrentResults( + results, + searchesPerformed.filter((search) => + search.errors.some( + (err) => + !err.includes(FAILED_CREATE_QUERY_MAX_CLAUSE) && + !err.includes(MANY_NESTED_CLAUSES_ERR) + ) + ) + ); + + // push warning message to appear in rule execution log + results.warningMessages.push( + `maxClauseCount error received from elasticsearch (${errorType}), setting IM rule page size to ${maxClauseCountValue}` + ); + } else { + results = combineConcurrentResults(results, searchesPerformed); + } documentCount -= list.hits.hits.length; ruleExecutionLogger.debug( `Concurrent indicator match searches completed with ${results.createdSignalsCount} signals found`, @@ -212,26 +261,33 @@ export const createThreatSignals = async ({ break; } ruleExecutionLogger.debug(`Documents items left to check are ${documentCount}`); + if (maxClauseCountValue > Number.NEGATIVE_INFINITY) { + ruleExecutionLogger.debug(`Re-running search since we hit max clause count error`); + + // re-run search with smaller max clause count; + list = await getDocumentList({ searchAfter: undefined }); + documentCount = totalDocumentCount; + } else { + const sortIds = getSafeSortIds(list.hits.hits[list.hits.hits.length - 1].sort); + + // ES can return negative sort id for date field, when sort order set to desc + // this could happen when event has empty sort field + // https://github.com/elastic/kibana/issues/174573 (happens to IM rule only since it uses desc order for events search) + // when negative sort id used in subsequent request it fails, so when negative sort value found we don't do next request + const hasNegativeDateSort = sortIds?.some((val) => val < 0); + + if (hasNegativeDateSort) { + ruleExecutionLogger.debug( + `Negative date sort id value encountered: ${sortIds}. Threat search stopped.` + ); + + break; + } - const sortIds = getSafeSortIds(list.hits.hits[list.hits.hits.length - 1].sort); - - // ES can return negative sort id for date field, when sort order set to desc - // this could happen when event has empty sort field - // https://github.com/elastic/kibana/issues/174573 (happens to IM rule only since it uses desc order for events search) - // when negative sort id used in subsequent request it fails, so when negative sort value found we don't do next request - const hasNegativeDateSort = sortIds?.some((val) => val < 0); - - if (hasNegativeDateSort) { - ruleExecutionLogger.debug( - `Negative date sort id value encountered: ${sortIds}. Threat search stopped.` - ); - - break; + list = await getDocumentList({ + searchAfter: sortIds, + }); } - - list = await getDocumentList({ - searchAfter: sortIds, - }); } }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.test.ts index 2764316df4ccc..1eb1269977cd7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.test.ts @@ -20,6 +20,7 @@ import { encodeThreatMatchNamedQuery, getMatchedFields, getSignalValueMap, + getMaxClauseCountErrorValue, } from './utils'; describe('utils', () => { @@ -948,6 +949,138 @@ describe('utils', () => { }); }); + describe('getMaxClauseCountErrorValue', () => { + test('should return Number.NEGATIVE_INFINITY when no max clause count error encountered', () => { + const searchesPerformed: SearchAfterAndBulkCreateReturnType[] = [ + { + success: true, + warning: false, + searchAfterTimes: ['10', '20', '30'], + bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], + lastLookBackDate: undefined, + createdSignalsCount: 3, + createdSignals: Array(3).fill(sampleSignalHit()), + errors: [], + warningMessages: [], + }, + ]; + + const noMaxClauseCountErrorFound = getMaxClauseCountErrorValue( + searchesPerformed, + 2, + 10000, + undefined + ); + expect(noMaxClauseCountErrorFound.maxClauseCountValue).toEqual(Number.NEGATIVE_INFINITY); + }); + + test('should return parsed max clause count when error message received is "failed to create query"', () => { + const threatEntries = 2; + const searchesPerformed: SearchAfterAndBulkCreateReturnType[] = [ + { + success: false, + warning: false, + searchAfterTimes: ['10', '20', '30'], + bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], + lastLookBackDate: undefined, + createdSignalsCount: 3, + createdSignals: Array(3).fill(sampleSignalHit()), + errors: [ + 'ResponseError: search_phase_execution_exception \ + Root causes:\ + query_shard_exception: failed to create query: maxClauseCount is set to 4096', + ], + warningMessages: [], + }, + ]; + + const maxClauseCountErrorValueFound = getMaxClauseCountErrorValue( + searchesPerformed, + 2, + 10000, + undefined + ); + + const newPageSize = (4096 - 1) / (threatEntries + 1); // 1365 + expect(maxClauseCountErrorValueFound.maxClauseCountValue).toEqual(newPageSize); + }); + + test('should return parsed max clause count when error message received is "Query contains too many nested clauses"', () => { + const threatEntries = 2; + const searchesPerformed: SearchAfterAndBulkCreateReturnType[] = [ + { + success: false, + warning: false, + searchAfterTimes: ['10', '20', '30'], + bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], + lastLookBackDate: undefined, + createdSignalsCount: 3, + createdSignals: Array(3).fill(sampleSignalHit()), + errors: [ + 'Searching events operation failed: ResponseError: search_phase_execution_exception\ + Root causes:\ + too_many_nested_clauses: too_many_nested_clauses: Query contains too many nested clauses; maxClauseCount is set to 9362', + ], + warningMessages: [], + }, + ]; + + const maxClauseCountErrorValueFound = getMaxClauseCountErrorValue( + searchesPerformed, + 2, + 10000, + undefined + ); + + const newPageSize = Math.floor((9362 - 1) / (2 * (threatEntries + 1))); // 1560 + expect(maxClauseCountErrorValueFound.maxClauseCountValue).toEqual(newPageSize); + }); + + test('should return parsed max clause count when error message received is "Query contains too many nested clauses" and previously calculated chunk size was not small enough', () => { + const threatEntries = 2; + const searchesPerformed: SearchAfterAndBulkCreateReturnType[] = [ + { + success: false, + warning: false, + searchAfterTimes: ['10', '20', '30'], + bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], + lastLookBackDate: undefined, + createdSignalsCount: 3, + createdSignals: Array(3).fill(sampleSignalHit()), + errors: [ + 'Searching events operation failed: ResponseError: search_phase_execution_exception\ + Root causes:\ + too_many_nested_clauses: too_many_nested_clauses: Query contains too many nested clauses; maxClauseCount is set to 9362', + ], + warningMessages: [], + }, + ]; + + const maxClauseCountErrorValueFound = getMaxClauseCountErrorValue( + searchesPerformed, + 2, + 10000, + undefined + ); + + const newPageSize = Math.floor((9362 - 1) / (2 * (threatEntries + 1))); // 1560 + expect(maxClauseCountErrorValueFound.maxClauseCountValue).toEqual(newPageSize); + + const newMaxClouseCountErrorValue = getMaxClauseCountErrorValue( + searchesPerformed, + 2, + maxClauseCountErrorValueFound.maxClauseCountValue, + undefined + ); + const betterValue = Math.floor(maxClauseCountErrorValueFound.maxClauseCountValue / 2); // 780 + expect(newMaxClouseCountErrorValue.maxClauseCountValue).toEqual(betterValue); + }); + }); + describe('getSignalValueMap', () => { it('return empty object if there no events', () => { const valueMap = getSignalValueMap({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.ts index cdb2fb808898a..2c1f74e99e925 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/utils.ts @@ -8,7 +8,11 @@ import moment from 'moment'; import type { ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; -import { get } from 'lodash'; +import { get, isEmpty } from 'lodash'; + +import { TelemetryChannel } from '../../../../telemetry/types'; +import type { ITelemetryEventsSender } from '../../../../telemetry/sender'; + import type { SearchAfterAndBulkCreateReturnType, SignalSourceHit } from '../../types'; import { parseInterval } from '../../utils/utils'; import { ThreatMatchQueryType } from './types'; @@ -22,6 +26,10 @@ import type { ThreatMatchNamedQuery, } from './types'; +export const MANY_NESTED_CLAUSES_ERR = + 'Query contains too many nested clauses; maxClauseCount is set to'; +export const FAILED_CREATE_QUERY_MAX_CLAUSE = 'failed to create query: maxClauseCount is set to'; + /** * Given two timers this will take the max of each and add them to each other and return that addition. * Max(timer_array_1) + Max(timer_array_2) @@ -239,3 +247,78 @@ export const getSignalValueMap = ({ }); return acc; }, {}); + +export const getMaxClauseCountErrorValue = ( + searchesPerformed: SearchAfterAndBulkCreateReturnType[], + threatEntriesCount: number, + previousChunkSize: number, + eventsTelemetry: ITelemetryEventsSender | undefined +) => + searchesPerformed.reduce<{ + maxClauseCountValue: number; + errorType: string; + }>( + (acc, search) => { + const failedToCreateQueryMessage: string | undefined = search.errors.find((err) => + err.includes(FAILED_CREATE_QUERY_MAX_CLAUSE) + ); + + // the below error is specific to an error returned by getSignalsQueryMapFromThreatIndex + const tooManyNestedClausesMessage: string | undefined = search.errors.find((err) => + err.includes(MANY_NESTED_CLAUSES_ERR) + ); + + const regex = /[0-9]+/g; + const foundMaxClauseCountValue = failedToCreateQueryMessage?.match(regex)?.[0]; + const foundNestedClauseCountValue = tooManyNestedClausesMessage?.match(regex)?.[0]; + + if (foundNestedClauseCountValue != null && !isEmpty(foundNestedClauseCountValue)) { + const errorType = `${MANY_NESTED_CLAUSES_ERR} ${foundNestedClauseCountValue}`; + const tempVal = parseInt(foundNestedClauseCountValue, 10); + eventsTelemetry?.sendAsync(TelemetryChannel.DETECTION_ALERTS, [ + `Query contains too many nested clauses error received during IM search`, + ]); + + // minus 1 since the max clause count value is exclusive + // multiplying by two because we need to account for the + // threat fields and event fields. A single threat entries count + // is comprised of two fields, one field from the threat index + // and another field from the event index. so we need to multiply by 2 + // to cover the fact that the nested clause error happens + // because we are searching over event and threat fields. + // so we need to make this smaller than a single 'failed to create query' + // max clause count error. + const val = Math.floor((tempVal - 1) / (2 * (threatEntriesCount + 1))); + // There is a chance the new calculated val still may yield a too many nested queries + // error message. In that case we want to make sure we don't fall into an infinite loop + // and so we send a new value that is guaranteed to be smaller than the previous one. + if (val >= previousChunkSize) { + return { + maxClauseCountValue: Math.floor(previousChunkSize / 2), + errorType, + }; + } + return { maxClauseCountValue: val, errorType }; + } else if (foundMaxClauseCountValue != null && !isEmpty(foundMaxClauseCountValue)) { + const errorType = `${FAILED_CREATE_QUERY_MAX_CLAUSE} ${foundNestedClauseCountValue}`; + const tempVal = parseInt(foundMaxClauseCountValue, 10); + eventsTelemetry?.sendAsync(TelemetryChannel.DETECTION_ALERTS, [ + `failed to create query error received during IM search`, + ]); + // minus 1 since the max clause count value is exclusive + // and we add 1 to threatEntries to increase the number of "buckets" + // that our searches are spread over, smaller buckets means less clauses + const val = Math.floor((tempVal - 1) / (threatEntriesCount + 1)); + return { + maxClauseCountValue: val, + errorType, + }; + } else { + return acc; + } + }, + { + maxClauseCountValue: Number.NEGATIVE_INFINITY, + errorType: 'no helpful error message available', + } + ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create_factory.ts index 1706f655d259b..49e03da44bb5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create_factory.ts @@ -170,7 +170,6 @@ export const searchAfterAndBulkCreateFactory = async ({ // if there is a sort id to continue the search_after with. if (includedEvents.length !== 0) { const enrichedEvents = await enrichment(includedEvents); - const bulkCreateResult = await bulkCreateExecutor({ enrichedEvents, toReturn, From 3609f882a523a6fa57eda3e01abfdcaf1beee5c9 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Mon, 29 Apr 2024 17:49:59 +0100 Subject: [PATCH 004/104] [ML] AIOps: Fixing pattern analysis action buttons layout (#181960) Widening actions column width. **Before** ![image](https://github.com/elastic/kibana/assets/22172091/cd39d806-4bf1-4697-a15b-ceede90bd730) **After** ![image](https://github.com/elastic/kibana/assets/22172091/6bf738a5-f110-4cf3-b530-e147341e1414) Also fixes similar issue with the annotations table in the anomaly explorer. Issue introduced in https://github.com/elastic/kibana/pull/180514 --- .../log_categorization/category_table/category_table.tsx | 2 +- .../annotations/annotations_table/annotations_table.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx index fc2d4b559e859..cf103f4905b20 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx @@ -194,7 +194,7 @@ export const CategoryTable: FC = ({ defaultMessage: 'Actions', }), sortable: false, - width: '60px', + width: '65px', actions: [ { name: labels.singleSelect.in, diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js index 7703ca87317e1..9436209c5f3bb 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js @@ -692,7 +692,7 @@ class AnnotationsTableUI extends Component { columns.push( { align: RIGHT_ALIGNMENT, - width: '60px', + width: '65px', name: i18n.translate('xpack.ml.annotationsTable.actionsColumnName', { defaultMessage: 'Actions', }), From 659f373e1fcd81fdf8ad916a67d9b328460d9f2d Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:14:09 -0700 Subject: [PATCH 005/104] [ML] Log rate analysis EUI table fixes (#181908) ## Summary closes https://github.com/elastic/kibana/issues/181804. Follow up to https://github.com/elastic/kibana/pull/180514 --- .../log_rate_analysis_results_table.tsx | 5 +++-- .../log_rate_analysis_results_table_groups.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx index fe13c7585893d..ac9ae24987b94 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx @@ -168,12 +168,13 @@ export const LogRateAnalysisResultsTable: FC = )} - {fieldName} + + {fieldName} + ); }, sortable: true, - truncateText: true, valign: 'middle', }, { diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx index 2d5acb8057679..1df6550309ae9 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx @@ -254,7 +254,7 @@ export const LogRateAnalysisResultsGroupsTable: FC Date: Mon, 29 Apr 2024 13:43:17 -0400 Subject: [PATCH 006/104] [Embeddables Rebuild] Restrict types & remove per panel versioning (#181751) Removes per-panel versioning and makes a few changes to further lock down types to make the new embeddable system more consistent and less error-prone. --- .../public/app/render_examples.tsx | 6 +-- .../create_eui_markdown_action.tsx | 3 +- .../eui_markdown_react_embeddable.tsx | 7 +-- .../field_list/create_field_list_action.tsx | 3 +- .../field_list_react_embeddable.tsx | 2 +- .../register_add_search_panel_action.tsx | 4 +- .../search/search_embeddable_renderer.tsx | 4 +- .../search/search_react_embeddable.tsx | 8 ++- .../public/react_embeddables/search/types.ts | 11 ++-- .../interfaces/can_add_new_panel.ts | 4 +- .../interfaces/last_saved_state.ts | 25 +++++---- .../interfaces/presentation_container.ts | 9 ++-- .../interfaces/serialized_state.ts | 3 +- .../comparators/fallback_comparator.ts | 24 +++++++++ .../comparators/index.ts | 1 + .../comparators/types.ts | 2 +- .../presentation_publishing/index.ts | 1 + .../interfaces/fetch/initialize_time_range.ts | 2 +- .../component/grid/dashboard_grid_item.tsx | 13 +---- .../embeddable/dashboard_container.tsx | 1 - .../react_embeddable_unsaved_changes.test.tsx | 4 +- .../react_embeddable_unsaved_changes.ts | 23 ++++---- .../public/react_embeddable_system/types.ts | 54 +++++++++++++++---- .../public/actions/create_image_action.ts | 3 +- .../get_image_embeddable_factory.tsx | 10 ++-- .../open_lens_config/create_action_helpers.ts | 2 +- .../anomaly_swimlane_embeddable_factory.tsx | 14 +++-- .../embeddables/anomaly_swimlane/types.ts | 11 ++++ ...ingle_metric_viewer_embeddable_factory.tsx | 14 +++-- x-pack/plugins/ml/public/embeddables/types.ts | 21 ++++---- 30 files changed, 182 insertions(+), 107 deletions(-) create mode 100644 packages/presentation/presentation_publishing/comparators/fallback_comparator.ts diff --git a/examples/embeddable_examples/public/app/render_examples.tsx b/examples/embeddable_examples/public/app/render_examples.tsx index c3e9b0a79a55b..f956a71711c7c 100644 --- a/examples/embeddable_examples/public/app/render_examples.tsx +++ b/examples/embeddable_examples/public/app/render_examples.tsx @@ -24,7 +24,7 @@ import { TimeRange } from '@kbn/es-query'; import { useBatchedOptionalPublishingSubjects } from '@kbn/presentation-publishing'; import { SearchEmbeddableRenderer } from '../react_embeddables/search/search_embeddable_renderer'; import { SEARCH_EMBEDDABLE_ID } from '../react_embeddables/search/constants'; -import type { Api, State } from '../react_embeddables/search/types'; +import type { SearchApi, SearchSerializedState } from '../react_embeddables/search/types'; export const RenderExamples = () => { const initialState = useMemo(() => { @@ -48,7 +48,7 @@ export const RenderExamples = () => { // only run onMount }, []); - const [api, setApi] = useState(null); + const [api, setApi] = useState(null); const [hidePanelChrome, setHidePanelChrome] = useState(false); const [dataLoading, timeRange] = useBatchedOptionalPublishingSubjects( api?.dataLoading, @@ -104,7 +104,7 @@ export const RenderExamples = () => { - + key={hidePanelChrome ? 'hideChrome' : 'showChrome'} type={SEARCH_EMBEDDABLE_ID} state={initialState} diff --git a/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx b/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx index 21306a4037262..cd95ba582d2d1 100644 --- a/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx @@ -12,6 +12,7 @@ import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { addPanelGrouping } from '../add_panel_grouping'; import { ADD_EUI_MARKDOWN_ACTION_ID, EUI_MARKDOWN_ID } from './constants'; +import { MarkdownEditorSerializedState } from './types'; // ----------------------------------------------------------------------------- // Create and register an action which allows this embeddable to be created from @@ -27,7 +28,7 @@ export const registerCreateEuiMarkdownAction = (uiActions: UiActionsStart) => { }, execute: async ({ embeddable }) => { if (!apiCanAddNewPanel(embeddable)) throw new IncompatibleActionError(); - embeddable.addNewPanel( + embeddable.addNewPanel( { panelType: EUI_MARKDOWN_ID, initialState: { content: '# hello world!' }, diff --git a/examples/embeddable_examples/public/react_embeddables/eui_markdown/eui_markdown_react_embeddable.tsx b/examples/embeddable_examples/public/react_embeddables/eui_markdown/eui_markdown_react_embeddable.tsx index 3a79952e16223..64cdf1cb06e08 100644 --- a/examples/embeddable_examples/public/react_embeddables/eui_markdown/eui_markdown_react_embeddable.tsx +++ b/examples/embeddable_examples/public/react_embeddables/eui_markdown/eui_markdown_react_embeddable.tsx @@ -26,12 +26,7 @@ export const markdownEmbeddableFactory: ReactEmbeddableFactory< MarkdownEditorApi > = { type: EUI_MARKDOWN_ID, - deserializeState: (state) => { - /** - * Here we can run clientside migrations and inject references. - */ - return state.rawState as MarkdownEditorSerializedState; - }, + deserializeState: (state) => state.rawState, /** * The buildEmbeddable function is async so you can async import the component or load a saved * object here. The loading will be handed gracefully by the Presentation Container. diff --git a/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx b/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx index 8e02aa6e385e0..7aa799a55f6e2 100644 --- a/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx @@ -12,6 +12,7 @@ import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; import { ADD_FIELD_LIST_ACTION_ID, FIELD_LIST_ID } from './constants'; +import { FieldListSerializedStateState } from './types'; import { addPanelGrouping } from '../add_panel_grouping'; export const registerCreateFieldListAction = (uiActions: UiActionsPublicStart) => { @@ -24,7 +25,7 @@ export const registerCreateFieldListAction = (uiActions: UiActionsPublicStart) = }, execute: async ({ embeddable }) => { if (!apiCanAddNewPanel(embeddable)) throw new IncompatibleActionError(); - embeddable.addNewPanel({ + embeddable.addNewPanel({ panelType: FIELD_LIST_ID, }); }, diff --git a/examples/embeddable_examples/public/react_embeddables/field_list/field_list_react_embeddable.tsx b/examples/embeddable_examples/public/react_embeddables/field_list/field_list_react_embeddable.tsx index c7067cba6ce8c..0c7d3d127efb9 100644 --- a/examples/embeddable_examples/public/react_embeddables/field_list/field_list_react_embeddable.tsx +++ b/examples/embeddable_examples/public/react_embeddables/field_list/field_list_react_embeddable.tsx @@ -66,7 +66,7 @@ export const getFieldListFactory = ( > = { type: FIELD_LIST_ID, deserializeState: (state) => { - const serializedState = cloneDeep(state.rawState) as FieldListSerializedStateState; + const serializedState = cloneDeep(state.rawState); // inject the reference const dataViewIdRef = state.references?.find( (ref) => ref.name === FIELD_LIST_DATA_VIEW_REF_NAME diff --git a/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx b/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx index 391a9e3c370d4..cb20f288bf032 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx @@ -11,6 +11,7 @@ import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { addPanelGrouping } from '../add_panel_grouping'; import { ADD_SEARCH_ACTION_ID, SEARCH_EMBEDDABLE_ID } from './constants'; +import { SearchSerializedState } from './types'; export const registerAddSearchPanelAction = (uiActions: UiActionsStart) => { uiActions.registerAction({ @@ -23,10 +24,9 @@ export const registerAddSearchPanelAction = (uiActions: UiActionsStart) => { }, execute: async ({ embeddable }) => { if (!apiCanAddNewPanel(embeddable)) throw new IncompatibleActionError(); - embeddable.addNewPanel( + embeddable.addNewPanel( { panelType: SEARCH_EMBEDDABLE_ID, - initialState: {}, }, true ); diff --git a/examples/embeddable_examples/public/react_embeddables/search/search_embeddable_renderer.tsx b/examples/embeddable_examples/public/react_embeddables/search/search_embeddable_renderer.tsx index 0fa6e785b72c1..39fa75234e3f4 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/search_embeddable_renderer.tsx +++ b/examples/embeddable_examples/public/react_embeddables/search/search_embeddable_renderer.tsx @@ -10,7 +10,7 @@ import React, { useEffect, useMemo } from 'react'; import { BehaviorSubject } from 'rxjs'; import { TimeRange } from '@kbn/es-query'; import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public'; -import type { Api, State } from './types'; +import type { SearchApi, SearchSerializedState } from './types'; import { SEARCH_EMBEDDABLE_ID } from './constants'; interface Props { @@ -42,7 +42,7 @@ export function SearchEmbeddableRenderer(props: Props) { return (
    - + type={SEARCH_EMBEDDABLE_ID} state={initialState} parentApi={parentApi} diff --git a/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx b/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx index e6fd182319631..3664c1cb4a411 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx +++ b/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx @@ -18,14 +18,12 @@ import React, { useEffect } from 'react'; import { BehaviorSubject, switchMap, tap } from 'rxjs'; import { SEARCH_EMBEDDABLE_ID } from './constants'; import { getCount } from './get_count'; -import { Api, Services, State } from './types'; +import { SearchApi, Services, SearchSerializedState } from './types'; export const getSearchEmbeddableFactory = (services: Services) => { - const factory: ReactEmbeddableFactory = { + const factory: ReactEmbeddableFactory = { type: SEARCH_EMBEDDABLE_ID, - deserializeState: (state) => { - return state.rawState as State; - }, + deserializeState: (state) => state.rawState, buildEmbeddable: async (state, buildApi, uuid, parentApi) => { const timeRange = initializeTimeRange(state); const defaultDataView = await services.dataViews.getDefaultDataView(); diff --git a/examples/embeddable_examples/public/react_embeddables/search/types.ts b/examples/embeddable_examples/public/react_embeddables/search/types.ts index dffe119eee7a0..835b2380d46a7 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/types.ts +++ b/examples/embeddable_examples/public/react_embeddables/search/types.ts @@ -9,23 +9,18 @@ import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; -import { TimeRange } from '@kbn/es-query'; import { HasParentApi, PublishesDataLoading, PublishesDataViews, PublishesUnifiedSearch, PublishesWritableUnifiedSearch, + SerializedTimeRange, } from '@kbn/presentation-publishing'; -export interface State { - /* - * Time range only applied to this embeddable, overrides parentApi.timeRange$ - */ - timeRange: TimeRange | undefined; -} +export type SearchSerializedState = SerializedTimeRange; -export type Api = DefaultEmbeddableApi & +export type SearchApi = DefaultEmbeddableApi & PublishesDataViews & PublishesDataLoading & Pick & diff --git a/packages/presentation/presentation_containers/interfaces/can_add_new_panel.ts b/packages/presentation/presentation_containers/interfaces/can_add_new_panel.ts index 22358b4398872..bbc7e7b3e5141 100644 --- a/packages/presentation/presentation_containers/interfaces/can_add_new_panel.ts +++ b/packages/presentation/presentation_containers/interfaces/can_add_new_panel.ts @@ -12,8 +12,8 @@ import { PanelPackage } from './presentation_container'; * This API can add a new panel as a child. */ export interface CanAddNewPanel { - addNewPanel: ( - panel: PanelPackage, + addNewPanel: ( + panel: PanelPackage, displaySuccessMessage?: boolean ) => Promise; } diff --git a/packages/presentation/presentation_containers/interfaces/last_saved_state.ts b/packages/presentation/presentation_containers/interfaces/last_saved_state.ts index cbbe26f490442..b4e4664920f11 100644 --- a/packages/presentation/presentation_containers/interfaces/last_saved_state.ts +++ b/packages/presentation/presentation_containers/interfaces/last_saved_state.ts @@ -13,7 +13,9 @@ import { SerializedPanelState } from './serialized_state'; export interface PublishesLastSavedState { lastSavedState: Subject; // a notification that the last saved state has changed - getLastSavedStateForChild: (childId: string) => SerializedPanelState | undefined; + getLastSavedStateForChild: ( + childId: string + ) => SerializedPanelState | undefined; } export const apiPublishesLastSavedState = (api: unknown): api is PublishesLastSavedState => { @@ -24,22 +26,25 @@ export const apiPublishesLastSavedState = (api: unknown): api is PublishesLastSa ); }; -export const getLastSavedStateSubjectForChild = ( +export const getLastSavedStateSubjectForChild = < + SerializedState extends object = object, + RuntimeState extends object = object +>( parentApi: unknown, childId: string, - deserializer?: (state: SerializedPanelState) => StateType -): PublishingSubject | undefined => { + deserializer: (state: SerializedPanelState) => RuntimeState +): PublishingSubject | undefined => { if (!parentApi) return; - const fetchLastSavedState = (): StateType | undefined => { + const fetchLastSavedState = (): RuntimeState | undefined => { if (!apiPublishesLastSavedState(parentApi)) return; - const rawLastSavedState = parentApi.getLastSavedStateForChild(childId); + const rawLastSavedState = parentApi.getLastSavedStateForChild(childId); if (rawLastSavedState === undefined) return; - return deserializer - ? deserializer(rawLastSavedState) - : (rawLastSavedState.rawState as StateType); + return deserializer(rawLastSavedState); }; - const lastSavedStateForChild = new BehaviorSubject(fetchLastSavedState()); + const lastSavedStateForChild = new BehaviorSubject( + fetchLastSavedState() + ); if (!apiPublishesLastSavedState(parentApi)) return; parentApi.lastSavedState .pipe( diff --git a/packages/presentation/presentation_containers/interfaces/presentation_container.ts b/packages/presentation/presentation_containers/interfaces/presentation_container.ts index b89562fff773b..92c69c6a8aa82 100644 --- a/packages/presentation/presentation_containers/interfaces/presentation_container.ts +++ b/packages/presentation/presentation_containers/interfaces/presentation_container.ts @@ -15,9 +15,9 @@ import { import { apiCanAddNewPanel, CanAddNewPanel } from './can_add_new_panel'; import { PublishesSettings } from './publishes_settings'; -export interface PanelPackage { +export interface PanelPackage { panelType: string; - initialState?: object; + initialState?: SerializedState; } export interface PresentationContainer @@ -25,7 +25,10 @@ export interface PresentationContainer CanAddNewPanel { removePanel: (panelId: string) => void; canRemovePanels?: () => boolean; - replacePanel: (idToRemove: string, newPanel: PanelPackage) => Promise; + replacePanel: ( + idToRemove: string, + newPanel: PanelPackage + ) => Promise; children$: PublishingSubject<{ [key: string]: unknown }>; } diff --git a/packages/presentation/presentation_containers/interfaces/serialized_state.ts b/packages/presentation/presentation_containers/interfaces/serialized_state.ts index b776ccf9ae59d..f56dd215bbcda 100644 --- a/packages/presentation/presentation_containers/interfaces/serialized_state.ts +++ b/packages/presentation/presentation_containers/interfaces/serialized_state.ts @@ -14,8 +14,7 @@ import { Reference } from '@kbn/content-management-utils'; */ export interface SerializedPanelState { references?: Reference[]; - rawState: RawStateType | undefined; - version?: string; + rawState: RawStateType; } export interface HasSerializableState { diff --git a/packages/presentation/presentation_publishing/comparators/fallback_comparator.ts b/packages/presentation/presentation_publishing/comparators/fallback_comparator.ts new file mode 100644 index 0000000000000..dc2c70fb866fe --- /dev/null +++ b/packages/presentation/presentation_publishing/comparators/fallback_comparator.ts @@ -0,0 +1,24 @@ +/* + * 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 { BehaviorSubject } from 'rxjs'; +import { PublishingSubject } from '../publishing_subject'; +import { ComparatorDefinition } from './types'; + +/** + * Comparators are required for every runtime state key. Occasionally, a comparator may + * actually be optional. In those cases, implementors can fall back to this blank definition + * which will always return 'true'. + */ +export const getUnchangingComparator = < + State extends object, + Key extends keyof State +>(): ComparatorDefinition => { + const subj = new BehaviorSubject(null as never); + return [subj as unknown as PublishingSubject, () => {}, () => true]; +}; diff --git a/packages/presentation/presentation_publishing/comparators/index.ts b/packages/presentation/presentation_publishing/comparators/index.ts index 788c811805e3b..c870fbca9daf8 100644 --- a/packages/presentation/presentation_publishing/comparators/index.ts +++ b/packages/presentation/presentation_publishing/comparators/index.ts @@ -8,3 +8,4 @@ export type { ComparatorFunction, ComparatorDefinition, StateComparators } from './types'; export { getInitialValuesFromComparators, runComparators } from './state_comparators'; +export { getUnchangingComparator } from './fallback_comparator'; diff --git a/packages/presentation/presentation_publishing/comparators/types.ts b/packages/presentation/presentation_publishing/comparators/types.ts index dd8bf272452cd..2bedf43096467 100644 --- a/packages/presentation/presentation_publishing/comparators/types.ts +++ b/packages/presentation/presentation_publishing/comparators/types.ts @@ -22,5 +22,5 @@ export type ComparatorDefinition = [ ]; export type StateComparators = { - [KeyType in keyof StateType]: ComparatorDefinition; + [KeyType in keyof Required]: ComparatorDefinition; }; diff --git a/packages/presentation/presentation_publishing/index.ts b/packages/presentation/presentation_publishing/index.ts index 6223c7cab4245..720663374cf72 100644 --- a/packages/presentation/presentation_publishing/index.ts +++ b/packages/presentation/presentation_publishing/index.ts @@ -17,6 +17,7 @@ export interface EmbeddableApiContext { export { getInitialValuesFromComparators, runComparators, + getUnchangingComparator, type ComparatorDefinition, type ComparatorFunction, type StateComparators, diff --git a/packages/presentation/presentation_publishing/interfaces/fetch/initialize_time_range.ts b/packages/presentation/presentation_publishing/interfaces/fetch/initialize_time_range.ts index d2b3c2e52d3c7..4be48a5062c7f 100644 --- a/packages/presentation/presentation_publishing/interfaces/fetch/initialize_time_range.ts +++ b/packages/presentation/presentation_publishing/interfaces/fetch/initialize_time_range.ts @@ -13,7 +13,7 @@ import { StateComparators } from '../../comparators'; import { PublishesWritableTimeRange } from './publishes_unified_search'; export interface SerializedTimeRange { - timeRange: TimeRange | undefined; + timeRange?: TimeRange | undefined; } export const initializeTimeRange = ( diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx index 6b3095e21ecb7..49a24e8bfacb6 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx @@ -120,7 +120,7 @@ export const Item = React.forwardRef( key={`${type}_${id}`} panelProps={panelProps} onApiAvailable={(api) => container.registerChildApi(api)} - state={{ rawState: panel.explicitInput as object, version: panel.version, references }} + state={{ rawState: panel.explicitInput as object, references }} /> ); } @@ -134,16 +134,7 @@ export const Item = React.forwardRef( {...panelProps} /> ); - }, [ - id, - container, - type, - index, - useMargins, - onPanelStatusChange, - panel.explicitInput, - panel.version, - ]); + }, [id, container, type, index, useMargins, onPanelStatusChange, panel.explicitInput]); return (
    { parentApi = { ...getMockPresentationContainer(), - getLastSavedStateForChild: () => ({ rawState: lastSavedState }), + getLastSavedStateForChild: () => ({ + rawState: lastSavedState as SerializedState, + }), lastSavedState: new Subject(), }; return startTrackingEmbeddableUnsavedChanges('id', parentApi, comparators, deserializeState); diff --git a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_unsaved_changes.ts b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_unsaved_changes.ts index 939a325a05d19..4df8bd9df287a 100644 --- a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_unsaved_changes.ts +++ b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_unsaved_changes.ts @@ -27,15 +27,18 @@ const getDefaultDiffingApi = () => { }; }; -export const startTrackingEmbeddableUnsavedChanges = ( +export const startTrackingEmbeddableUnsavedChanges = < + SerializedState extends object = object, + RuntimeState extends object = object +>( uuid: string, parentApi: unknown, - comparators: StateComparators, - deserializeState: (state: SerializedPanelState) => StateType + comparators: StateComparators, + deserializeState: (state: SerializedPanelState) => RuntimeState ) => { if (Object.keys(comparators).length === 0) return getDefaultDiffingApi(); - const lastSavedStateSubject = getLastSavedStateSubjectForChild( + const lastSavedStateSubject = getLastSavedStateSubjectForChild( parentApi, uuid, deserializeState @@ -43,14 +46,14 @@ export const startTrackingEmbeddableUnsavedChanges = > = []; - const comparatorKeys: Array = []; - for (const key of Object.keys(comparators) as Array) { + const comparatorKeys: Array = []; + for (const key of Object.keys(comparators) as Array) { const comparatorSubject = comparators[key][0]; // 0th element of tuple is the subject comparatorSubjects.push(comparatorSubject as PublishingSubject); comparatorKeys.push(key); } - const unsavedChanges = new BehaviorSubject | undefined>( + const unsavedChanges = new BehaviorSubject | undefined>( runComparators( comparators, comparatorKeys, @@ -64,9 +67,9 @@ export const startTrackingEmbeddableUnsavedChanges = comparatorKeys.reduce((acc, key, index) => { - acc[key] = latestStates[index] as StateType[typeof key]; + acc[key] = latestStates[index] as RuntimeState[typeof key]; return acc; - }, {} as Partial) + }, {} as Partial) ), combineLatestWith(lastSavedStateSubject) ) @@ -82,7 +85,7 @@ export const startTrackingEmbeddableUnsavedChanges = subscription.unsubscribe(), diff --git a/src/plugins/embeddable/public/react_embeddable_system/types.ts b/src/plugins/embeddable/public/react_embeddable_system/types.ts index 5c3fa76e86997..e79879a5b4487 100644 --- a/src/plugins/embeddable/public/react_embeddable_system/types.ts +++ b/src/plugins/embeddable/public/react_embeddable_system/types.ts @@ -19,29 +19,65 @@ export type ReactEmbeddableRegistration< * * Before adding anything to this interface, please be certain that it belongs in *every* embeddable. */ -export interface DefaultEmbeddableApi +export interface DefaultEmbeddableApi extends DefaultPresentationPanelApi, HasType, PublishesUnsavedChanges, - HasSerializableState {} + HasSerializableState {} +/** + * A subset of the default embeddable API used in registration to allow implementors to omit aspects + * of the API that will be automatically added by the system. + */ export type ReactEmbeddableApiRegistration< StateType extends object = object, ApiType extends DefaultEmbeddableApi = DefaultEmbeddableApi > = Omit; +/** + * The React Embeddable Factory interface is used to register a series of functions that + * create and manage an embeddable instance. + * + * Embeddables are React components that manage their own state, can be serialized and + * deserialized, and return an API that can be used to interact with them imperatively. + * provided by the parent, and will not save any state to an external store. + **/ export interface ReactEmbeddableFactory< - StateType extends object = object, - ApiType extends DefaultEmbeddableApi = DefaultEmbeddableApi + SerializedState extends object = object, + ApiType extends DefaultEmbeddableApi = DefaultEmbeddableApi, + RuntimeState extends object = SerializedState > { + /** + * A unique key for the type of this embeddable. The React Embeddable Renderer will use this type + * to find this factory. + */ type: string; - latestVersion?: string; - deserializeState: (state: SerializedPanelState) => StateType; + + /** + * A required synchronous function that transforms serialized state into runtime state. + * This will be used twice - once for the parent state, and once for the last saved state + * for comparison. + * + * This can also be used to: + * + * - Inject references provided by the parent + * - Migrate the state to a newer version (this must be undone when serializing) + */ + deserializeState: (state: SerializedPanelState) => RuntimeState; + + /** + * A required async function that builds your embeddable component and a linked API instance. The API + * and component will be combined together by the ReactEmbeddableRenderer. Initial state will contain the result of + * the deserialize function. + * + * The returned API must extend {@link HasSerializableState} which does the opposite of the deserializeState + * function. + */ buildEmbeddable: ( - initialState: StateType, + initialState: RuntimeState, buildApi: ( - apiRegistration: ReactEmbeddableApiRegistration, - comparators: StateComparators + apiRegistration: ReactEmbeddableApiRegistration, + comparators: StateComparators ) => ApiType, uuid: string, parentApi?: unknown diff --git a/src/plugins/image_embeddable/public/actions/create_image_action.ts b/src/plugins/image_embeddable/public/actions/create_image_action.ts index 8b001e2faa007..02cd8b26e1182 100644 --- a/src/plugins/image_embeddable/public/actions/create_image_action.ts +++ b/src/plugins/image_embeddable/public/actions/create_image_action.ts @@ -14,6 +14,7 @@ import { ADD_IMAGE_EMBEDDABLE_ACTION_ID, IMAGE_EMBEDDABLE_TYPE, } from '../image_embeddable/constants'; +import { ImageEmbeddableSerializedState } from '../image_embeddable/types'; import { uiActionsService } from '../services/kibana_services'; const parentApiIsCompatible = async (parentApi: unknown): Promise => { @@ -36,7 +37,7 @@ export const registerCreateImageAction = () => { try { const imageConfig = await openImageEditor({ parentApi: canAddNewPanelParent }); - canAddNewPanelParent.addNewPanel({ + canAddNewPanelParent.addNewPanel({ panelType: IMAGE_EMBEDDABLE_TYPE, initialState: { imageConfig }, }); diff --git a/src/plugins/image_embeddable/public/image_embeddable/get_image_embeddable_factory.tsx b/src/plugins/image_embeddable/public/image_embeddable/get_image_embeddable_factory.tsx index 5fea742afd8ca..d5b15122f70f1 100644 --- a/src/plugins/image_embeddable/public/image_embeddable/get_image_embeddable_factory.tsx +++ b/src/plugins/image_embeddable/public/image_embeddable/get_image_embeddable_factory.tsx @@ -14,7 +14,7 @@ import { EmbeddableEnhancedPluginStart } from '@kbn/embeddable-enhanced-plugin/p import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; import { i18n } from '@kbn/i18n'; import { PresentationContainer } from '@kbn/presentation-containers'; -import { initializeTitles } from '@kbn/presentation-publishing'; +import { getUnchangingComparator, initializeTitles } from '@kbn/presentation-publishing'; import { IMAGE_CLICK_TRIGGER } from '../actions'; import { openImageEditor } from '../components/image_editor/open_image_editor'; @@ -34,9 +34,7 @@ export const getImageEmbeddableFactory = ({ ImageEmbeddableApi > = { type: IMAGE_EMBEDDABLE_TYPE, - deserializeState: (state) => { - return state.rawState as ImageEmbeddableSerializedState; - }, + deserializeState: (state) => state.rawState, buildEmbeddable: async (initialState, buildApi, uuid) => { const { titlesApi, titleComparators, serializeTitles } = initializeTitles(initialState); @@ -86,7 +84,9 @@ export const getImageEmbeddableFactory = ({ }, { ...titleComparators, - ...(dynamicActionsApi?.dynamicActionsComparator ?? {}), + ...(dynamicActionsApi?.dynamicActionsComparator ?? { + enhancements: getUnchangingComparator(), + }), imageConfig: [ imageConfig$, (value) => imageConfig$.next(value), diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts index 5173c69c1d3f9..3e77f8979a872 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts @@ -98,7 +98,7 @@ export async function executeCreateAction({ dataView, }); - const embeddable = await api.addNewPanel({ + const embeddable = await api.addNewPanel({ panelType: 'lens', initialState: { attributes: attrs, diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx index 9092eb687e378..7306085b8d413 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx @@ -42,7 +42,11 @@ import { buildDataViewPublishingApi } from '../common/anomaly_detection_embeddab import { useReactEmbeddableExecutionContext } from '../common/use_embeddable_execution_context'; import { initializeSwimLaneControls } from './initialize_swim_lane_controls'; import { initializeSwimLaneDataFetcher } from './initialize_swim_lane_data_fetcher'; -import type { AnomalySwimLaneEmbeddableApi, AnomalySwimLaneEmbeddableState } from './types'; +import type { + AnomalySwimLaneEmbeddableApi, + AnomalySwimLaneEmbeddableState, + AnomalySwimlaneRuntimeState, +} from './types'; /** * Provides the services required by the Anomaly Swimlane Embeddable. @@ -84,12 +88,11 @@ export const getAnomalySwimLaneEmbeddableFactory = ( ) => { const factory: ReactEmbeddableFactory< AnomalySwimLaneEmbeddableState, - AnomalySwimLaneEmbeddableApi + AnomalySwimLaneEmbeddableApi, + AnomalySwimlaneRuntimeState > = { type: ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, - deserializeState: (state) => { - return state.rawState as AnomalySwimLaneEmbeddableState; - }, + deserializeState: (state) => state.rawState, buildEmbeddable: async (state, buildApi, uuid, parentApi) => { if (!apiHasExecutionContext(parentApi)) { throw new Error('Parent API does not have execution context'); @@ -154,6 +157,7 @@ export const getAnomalySwimLaneEmbeddableFactory = ( serializeState: () => { return { rawState: { + timeRange: undefined, ...serializeTitles(), ...serializeTimeRange(), ...serializeSwimLaneState(), diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/types.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/types.ts index 7326e3e29c80e..9e24c02f49c2b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/types.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/types.ts @@ -61,3 +61,14 @@ export function isSwimLaneEmbeddableContext(arg: unknown): arg is AnomalySwimLan export interface AnomalySwimLaneEmbeddableState extends SerializedTitles, AnomalySwimlaneEmbeddableCustomInput {} + +/** + * The subset of the Anomaly Swim Lane Embeddable state that is actually used by the swimlane embeddable. + * + * TODO: Ideally this should be the same as the AnomalySwimLaneEmbeddableState, but that type is used in many + * places, so we cannot change it at the moment. + */ +export type AnomalySwimlaneRuntimeState = Omit< + AnomalySwimLaneEmbeddableState, + 'id' | 'filters' | 'query' | 'refreshConfig' +>; diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx index 3ed124d5db40f..b46cda1520ba7 100644 --- a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx @@ -30,7 +30,11 @@ import { throttle } from 'lodash'; import { BehaviorSubject, Subscription } from 'rxjs'; import { ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE } from '..'; import type { MlPluginStart, MlStartDependencies } from '../../plugin'; -import type { SingleMetricViewerEmbeddableApi, SingleMetricViewerEmbeddableState } from '../types'; +import type { + SingleMetricViewerRuntimeState, + SingleMetricViewerEmbeddableApi, + SingleMetricViewerEmbeddableState, +} from '../types'; import { initializeSingleMetricViewerControls } from './single_metric_viewer_controls_initializer'; import { initializeSingleMetricViewerDataFetcher } from './single_metric_viewer_data_fetcher'; import { TimeSeriesExplorerEmbeddableChart } from '../../application/timeseriesexplorer/timeseriesexplorer_embeddable_chart'; @@ -56,12 +60,11 @@ export const getSingleMetricViewerEmbeddableFactory = ( ) => { const factory: ReactEmbeddableFactory< SingleMetricViewerEmbeddableState, - SingleMetricViewerEmbeddableApi + SingleMetricViewerEmbeddableApi, + SingleMetricViewerRuntimeState > = { type: ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE, - deserializeState: (state) => { - return state.rawState as SingleMetricViewerEmbeddableState; - }, + deserializeState: (state) => state.rawState, buildEmbeddable: async (state, buildApi, uuid, parentApi) => { const services = await getServices(getStartServices); const subscriptions = new Subscription(); @@ -93,6 +96,7 @@ export const getSingleMetricViewerEmbeddableFactory = ( serializeState: () => { return { rawState: { + timeRange: undefined, ...serializeTitles(), ...serializeTimeRange(), ...serializeSingleMetricViewerState(), diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts index 3f36e76ef3281..7e731e863239a 100644 --- a/x-pack/plugins/ml/public/embeddables/types.ts +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -92,16 +92,6 @@ export type AnomalySwimlaneEmbeddableServices = [ AnomalySwimlaneServices ]; -export interface AnomalySwimlaneEmbeddableCustomOutput { - perPage?: number; - fromPage?: number; - interval?: number; - indexPatterns: DataView[]; -} - -export type AnomalySwimlaneEmbeddableOutput = EmbeddableOutput & - AnomalySwimlaneEmbeddableCustomOutput; - export type EditSwimLaneActionApi = HasType & Partial>; @@ -166,6 +156,17 @@ export type SingleMetricViewerEmbeddableApi = PublishesWritablePanelTitle & SingleMetricViewerComponentApi; +/** + * The subset of the single metric viewer Embeddable state that is actually used by the single metric viewer embeddable. + * + * TODO: Ideally this should be the same as the SingleMetricViewerEmbeddableState, but that type is used in many + * places, so we cannot change it at the moment. + */ +export type SingleMetricViewerRuntimeState = Omit< + SingleMetricViewerEmbeddableState, + 'id' | 'filters' | 'query' | 'refreshConfig' +>; + export interface SingleMetricViewerComponentApi { functionDescription: PublishingSubject; jobIds: PublishingSubject; From 4ffe8c8b26a0f6fdb0abdbfbf07e875ad7f70435 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Mon, 29 Apr 2024 19:57:25 +0200 Subject: [PATCH 007/104] [Index Management] Disable toggling data retention in serverless (#181556) --- config/serverless.yml | 2 ++ .../test_suites/core_plugins/rendering.ts | 1 + .../helpers/setup_environment.tsx | 1 + .../public/application/app_context.tsx | 7 ++-- .../edit_data_retention_modal.tsx | 35 ++++++++++++++----- .../plugins/index_management/public/plugin.ts | 3 ++ .../plugins/index_management/public/types.ts | 1 + .../plugins/index_management/server/config.ts | 6 ++++ .../plugins/index_management/server/plugin.ts | 1 + .../plugins/index_management/server/types.ts | 1 + .../index_management/data_streams.ts | 15 ++------ 11 files changed, 50 insertions(+), 23 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index 7e18b184468ef..efe339e428392 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -48,6 +48,8 @@ xpack.index_management.enableIndexStats: false xpack.index_management.editableIndexSettings: limited # Disable Storage size column in the Data streams table from Index Management UI xpack.index_management.enableDataStreamsStorageColumn: false +# Disable toggle for enabling data retention in DSL form from Index Management UI +xpack.index_management.enableTogglingDataRetention: false # Keep deeplinks visible so that they are shown in the sidenav dev_tools.deeplinks.navLinkStatus: visible diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index b29b6e7eda491..1dd002b1ecf45 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -277,6 +277,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.index_management.editableIndexSettings (any)', 'xpack.index_management.enableDataStreamsStorageColumn (any)', 'xpack.infra.sources.default.fields.message (array)', + 'xpack.index_management.enableTogglingDataRetention (any)', // It's a boolean (any because schema.conditional) /** * Feature flags bellow are conditional based on traditional/serverless offering * and will all resolve to xpack.infra.featureFlags.* (boolean) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index 79165a4771ae8..e622a7e7e7023 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -84,6 +84,7 @@ const appDependencies = { enableIndexStats: true, editableIndexSettings: 'all', enableDataStreamsStorageColumn: true, + enableTogglingDataRetention: true, }, } as any; diff --git a/x-pack/plugins/index_management/public/application/app_context.tsx b/x-pack/plugins/index_management/public/application/app_context.tsx index f95fcde4395b5..460044312d23a 100644 --- a/x-pack/plugins/index_management/public/application/app_context.tsx +++ b/x-pack/plugins/index_management/public/application/app_context.tsx @@ -21,11 +21,11 @@ import { } from '@kbn/core/public'; import type { MlPluginStart } from '@kbn/ml-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; - -import { EuiBreadcrumb } from '@elastic/eui'; +import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { CloudSetup } from '@kbn/cloud-plugin/public'; import type { ConsolePluginStart } from '@kbn/console-plugin/public'; -import type { SettingsStart } from '@kbn/core-ui-settings-browser'; + +import { EuiBreadcrumb } from '@elastic/eui'; import { ExtensionsService } from '../services'; import { HttpService, NotificationService, UiMetricService } from './services'; import { IndexManagementBreadcrumb } from './services/breadcrumbs'; @@ -62,6 +62,7 @@ export interface AppDependencies { enableIndexStats: boolean; editableIndexSettings: 'all' | 'limited'; enableDataStreamsStorageColumn: boolean; + enableTogglingDataRetention: boolean; }; history: ScopedHistory; setBreadcrumbs: (type: IndexManagementBreadcrumb, additionalBreadcrumb?: EuiBreadcrumb) => void; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 713fdc8a709d5..dd2ec9efc5d46 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -19,6 +19,7 @@ import { EuiText, EuiCallOut, } from '@elastic/eui'; +import { has } from 'lodash'; import { ScopedHistory } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -193,6 +194,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ const { size, unit } = splitSizeAndUnits(lifecycle?.data_retention as string); const { services: { notificationService }, + config: { enableTogglingDataRetention }, } = useAppContext(); const { form } = useForm({ @@ -218,6 +220,16 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ return; } + // When enableTogglingDataRetention is disabled (ie: serverless) we don't mount + // the dataRetentionEnabled field in the UI, which means that the form state for + // this field regardless if it has defaultValue or if its set with form.setValue. + // This seems to be a design decision from the formlib and there doesnt seem to + // be a way around it AFAICT. + // So when that happens we want to make sure that the dataRetention is always enabled. + if (!has(data, 'dataRetentionEnabled')) { + data.dataRetentionEnabled = true; + } + return updateDataRetention(dataStreamName, data).then(({ data: responseData, error }) => { if (responseData) { const successMessage = i18n.translate( @@ -273,11 +285,13 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ )} - + {enableTogglingDataRetention && ( + + )} = ({ componentProps={{ fullWidth: false, euiFieldProps: { - disabled: formData.infiniteRetentionPeriod || !formData.dataRetentionEnabled, + disabled: + formData.infiniteRetentionPeriod || + (!formData.dataRetentionEnabled && enableTogglingDataRetention), 'data-test-subj': `dataRetentionValue`, min: 1, append: ( = ({ data-test-subj="infiniteRetentionPeriod" componentProps={{ euiFieldProps: { - disabled: !formData.dataRetentionEnabled, + disabled: !formData.dataRetentionEnabled && enableTogglingDataRetention, }, }} /> diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index baf00ab75f7b9..319d6b67c5f1a 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -44,6 +44,7 @@ export class IndexMgmtUIPlugin editableIndexSettings: 'all' | 'limited'; enableDataStreamsStorageColumn: boolean; isIndexManagementUiEnabled: boolean; + enableTogglingDataRetention: boolean; }; constructor(ctx: PluginInitializerContext) { @@ -58,6 +59,7 @@ export class IndexMgmtUIPlugin enableIndexStats, editableIndexSettings, enableDataStreamsStorageColumn, + enableTogglingDataRetention, } = ctx.config.get(); this.config = { isIndexManagementUiEnabled, @@ -66,6 +68,7 @@ export class IndexMgmtUIPlugin enableIndexStats: enableIndexStats ?? true, editableIndexSettings: editableIndexSettings ?? 'all', enableDataStreamsStorageColumn: enableDataStreamsStorageColumn ?? true, + enableTogglingDataRetention: enableTogglingDataRetention ?? true, }; } diff --git a/x-pack/plugins/index_management/public/types.ts b/x-pack/plugins/index_management/public/types.ts index e7f2013766b6f..e0be3cd891632 100644 --- a/x-pack/plugins/index_management/public/types.ts +++ b/x-pack/plugins/index_management/public/types.ts @@ -39,4 +39,5 @@ export interface ClientConfigType { enableIndexStats?: boolean; editableIndexSettings?: 'all' | 'limited'; enableDataStreamsStorageColumn?: boolean; + enableTogglingDataRetention?: boolean; } diff --git a/x-pack/plugins/index_management/server/config.ts b/x-pack/plugins/index_management/server/config.ts index 7ee8afc5af5e4..d0cb247e0d37a 100644 --- a/x-pack/plugins/index_management/server/config.ts +++ b/x-pack/plugins/index_management/server/config.ts @@ -52,6 +52,11 @@ const schemaLatest = schema.object( // We take this approach in order to have a central place (serverless.yml) for serverless config across Kibana serverless: schema.boolean({ defaultValue: true }), }), + enableTogglingDataRetention: offeringBasedSchema({ + // The toggle for enabling data retention for DSL in data streams UI is disabled in serverless; refer to the serverless.yml file as the source of truth + // We take this approach in order to have a central place (serverless.yml) for serverless config across Kibana + serverless: schema.boolean({ defaultValue: true }), + }), }, { defaultValue: undefined } ); @@ -64,6 +69,7 @@ const configLatest: PluginConfigDescriptor = { enableIndexStats: true, editableIndexSettings: true, enableDataStreamsStorageColumn: true, + enableTogglingDataRetention: true, }, schema: schemaLatest, deprecations: ({ unused }) => [unused('dev.enableIndexDetailsPage', { level: 'warning' })], diff --git a/x-pack/plugins/index_management/server/plugin.ts b/x-pack/plugins/index_management/server/plugin.ts index e7e2982a0e5c0..291e81042f0bc 100644 --- a/x-pack/plugins/index_management/server/plugin.ts +++ b/x-pack/plugins/index_management/server/plugin.ts @@ -57,6 +57,7 @@ export class IndexMgmtServerPlugin implements Plugin { const TEST_DS_NAME = 'test-ds-1'; - // FAILING: https://github.com/elastic/kibana/issues/181242 - describe.skip('Data Streams', function () { + describe('Data Streams', function () { // failsOnMKI, see https://github.com/elastic/kibana/issues/181242 this.tags(['failsOnMKI']); before(async () => { @@ -122,22 +121,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(await successToast.getVisibleText()).to.contain('Data retention updated'); }); - it('allows to disable data retention', async () => { + it('disabling data retention in serverless is not allowed', async () => { // Open details flyout await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); // Open the edit retention dialog await testSubjects.click('manageDataStreamButton'); await testSubjects.click('editDataRetentionButton'); - // Disable infinite retention - await testSubjects.click('dataRetentionEnabledField > input'); - - // Submit the form - await testSubjects.click('saveButton'); - - // Expect to see a success toast - const successToast = await toasts.getElementByIndex(1); - expect(await successToast.getVisibleText()).to.contain('Data retention disabled'); + expect(await testSubjects.exists('dataRetentionEnabledField')).to.be(false); }); }); }; From 5f4d863c62d50e1e142fbcaef3c1c27fde4cbce3 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 29 Apr 2024 12:31:47 -0600 Subject: [PATCH 008/104] [ML] Data Frame Analytics functional tests: ensure consistent testing of ROC chart in results (#181915) ## Summary Fixes https://github.com/elastic/kibana/issues/176938 Flaky test runner: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5783 In ML `data_frame_analytics.x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts` The `assertColorsInCanvasElement` has ongoing flakiness because of color variation dependent on then environment in which the test is run. Due to this, the specific color check for this particular test suite has been replaced with a basic chart check. The color assertion is less flaky in the other types of DFA creation so this case is still covered by those tests. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../classification_creation_saved_search.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts index eb81e2d8de15a..b3789ceeac28b 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts @@ -12,6 +12,7 @@ import type { FieldStatsType } from '../common/types'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); + const testSubjects = getService('testSubjects'); const editedDescription = 'Edited description'; describe('classification saved search creation', function () { @@ -684,19 +685,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('displays the ROC curve chart'); - // NOTE: Temporarily disabling these assertions since the colors can vary quite a bit on each run and cause flakiness - // Tracking in https://github.com/elastic/kibana/issues/176938 - - // await ml.commonUI.assertColorsInCanvasElement( - // 'mlDFAnalyticsClassificationExplorationRocCurveChart', - // testData.expected.rocCurveColorState, - // ['#000000'], - // undefined, - // undefined, - // // increased tolerance for ROC curve chart up from 10 to 20 - // // since the returned colors vary quite a bit on each run. - // 20 - // ); + // This is a basic check that the chart exists since the returned colors vary quite a bit on each run and cause flakiness. + await testSubjects.existOrFail('mlDFAnalyticsClassificationExplorationRocCurveChart'); await ml.commonUI.resetAntiAliasing(); }); From 57a27278e98b091cfbb087938da6357e037288a4 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 29 Apr 2024 20:59:22 +0200 Subject: [PATCH 009/104] [SLO Embeddable rebuild] move error budget embeddable to the new react registry (#181532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/elastic/kibana/issues/179294 ## 🍒 Summary This PR converts the `SLO Error budget burn down` embeddable to the new React Embeddable framework. There are no UI changes to the current embeddable and the behavior should be the same. I have a video of how the embeddable should work. https://github.com/elastic/kibana/assets/2852703/aaba8114-f74f-4dd7-8999-497bf9388562 ## ✔️ Acceptance criteria - A new `create_error_budget_action` action is created, which adds the `SLO Error budget burn down` option in the `Add panel` section - The `SLO Error budget burn down` menu option is grouped under `SLOs` menu - Clicking on the SLO name should open a `Flyout` with the SLO details - `Within the Flyout` the `Add to Dashboard` option while hovering on the Error Budget burn down should not be visible - On the `SLO Details` page, the `Add to Dashboard` option while hovering on the Error Budget burn down should be visible - Kibana screenshot tool should report no timeout error. - Clicking on the `Refresh` button should reload the embeddable - No reaction to the kql bar, datepicker or controls (New tickets will cover these after the migration, https://github.com/elastic/kibana/issues/181426 & https://github.com/elastic/kibana/issues/181498) Screenshot 2024-04-24 at 12 20 18 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../error_budget/{index.ts => constants.ts} | 3 +- ...rn_down.tsx => error_budget_burn_down.tsx} | 4 +- ...sx => error_budget_open_configuration.tsx} | 13 +-- .../error_budget_react_embeddable_factory.tsx | 103 +++++++++++++++++ .../slo/error_budget/slo_configuration.tsx | 5 +- .../slo_error_budget_embeddable.tsx | 104 ------------------ .../slo_error_budget_embeddable_factory.ts | 73 ------------ .../embeddable/slo/error_budget/types.ts | 32 +++++- .../components/error_budget_chart_panel.tsx | 4 +- .../slo/public/plugin.ts | 26 +++-- .../ui_actions/create_error_budget_action.tsx | 55 +++++++++ .../slo/public/ui_actions/index.ts | 6 +- .../observability_solution/slo/tsconfig.json | 1 + 13 files changed, 222 insertions(+), 207 deletions(-) rename x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/{index.ts => constants.ts} (62%) rename x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/{slo_error_budget_burn_down.tsx => error_budget_burn_down.tsx} (97%) rename x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/{handle_explicit_input.tsx => error_budget_open_configuration.tsx} (91%) create mode 100644 x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_react_embeddable_factory.tsx delete mode 100644 x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable.tsx delete mode 100644 x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable_factory.ts create mode 100644 x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/index.ts b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/constants.ts similarity index 62% rename from x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/index.ts rename to x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/constants.ts index edd11f1ce4f58..b4e3522840013 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/index.ts +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/constants.ts @@ -5,4 +5,5 @@ * 2.0. */ -export { SloErrorBudgetEmbeddableFactoryDefinition } from './slo_error_budget_embeddable_factory'; +export const SLO_ERROR_BUDGET_ID = 'SLO_ERROR_BUDGET_EMBEDDABLE'; +export const ADD_SLO_ERROR_BUDGET_ACTION_ID = 'CREATE_SLO_ERROR_BUDGET_EMBEDDABLE'; diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_burn_down.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_burn_down.tsx similarity index 97% rename from x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_burn_down.tsx rename to x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_burn_down.tsx index c176c83960f33..cba2ce0be6ccd 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_burn_down.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_burn_down.tsx @@ -18,7 +18,7 @@ import { useFetchSloDetails } from '../../../hooks/use_fetch_slo_details'; import { ErrorBudgetChart } from '../../../pages/slo_details/components/error_budget_chart'; import { EmbeddableSloProps } from './types'; -import { SloOverviewDetails } from '../common/slo_overview_details'; // TODO change to slo_details +import { SloOverviewDetails } from '../common/slo_overview_details'; import { ErrorBudgetHeader } from '../../../pages/slo_details/components/error_budget_header'; import { SLOGroupings } from '../../../pages/slos/components/common/slo_groupings'; @@ -111,7 +111,7 @@ export function SloErrorBudget({ } const hasGroupBy = slo.instanceId !== ALL_VALUE; return ( -
    +
    { const { overlays } = coreStart; const queryClient = new QueryClient(); diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_react_embeddable_factory.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_react_embeddable_factory.tsx new file mode 100644 index 0000000000000..63ebb3fb37205 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/error_budget_react_embeddable_factory.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import React, { useEffect } from 'react'; +import { Router } from '@kbn/shared-ux-router'; +import { createBrowserHistory } from 'history'; +import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; +import { + initializeTitles, + useBatchedPublishingSubjects, + fetch$, +} from '@kbn/presentation-publishing'; +import { BehaviorSubject, Subject } from 'rxjs'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { SLO_ERROR_BUDGET_ID } from './constants'; +import { SloErrorBudgetEmbeddableState, SloEmbeddableDeps, ErrorBudgetApi } from './types'; +import { SloErrorBudget } from './error_budget_burn_down'; + +export const getErrorBudgetPanelTitle = () => + i18n.translate('xpack.slo.errorBudgetEmbeddable.title', { + defaultMessage: 'SLO Error Budget burn down', + }); +const queryClient = new QueryClient(); + +export const getErrorBudgetEmbeddableFactory = (deps: SloEmbeddableDeps) => { + const factory: ReactEmbeddableFactory = { + type: SLO_ERROR_BUDGET_ID, + deserializeState: (state) => { + return state.rawState as SloErrorBudgetEmbeddableState; + }, + buildEmbeddable: async (state, buildApi, uuid, parentApi) => { + const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state); + const defaultTitle$ = new BehaviorSubject(getErrorBudgetPanelTitle()); + const sloId$ = new BehaviorSubject(state.sloId); + const sloInstanceId$ = new BehaviorSubject(state.sloInstanceId); + const reload$ = new Subject(); + + const api = buildApi( + { + ...titlesApi, + defaultPanelTitle: defaultTitle$, + serializeState: () => { + return { + rawState: { + ...serializeTitles(), + sloId: sloId$.getValue(), + sloInstanceId: sloInstanceId$.getValue(), + }, + }; + }, + }, + { + sloId: [sloId$, (value) => sloId$.next(value)], + sloInstanceId: [sloInstanceId$, (value) => sloInstanceId$.next(value)], + ...titleComparators, + } + ); + + const fetchSubscription = fetch$(api) + .pipe() + .subscribe((next) => { + reload$.next(next.isReload); + }); + + return { + api, + Component: () => { + const [sloId, sloInstanceId] = useBatchedPublishingSubjects(sloId$, sloInstanceId$); + + const I18nContext = deps.i18n.Context; + + useEffect(() => { + return () => { + fetchSubscription.unsubscribe(); + }; + }, []); + + return ( + + + + + + + + + + ); + }, + }; + }, + }; + return factory; +}; diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_configuration.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_configuration.tsx index 5cb1eb084593a..d83b5b574b193 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_configuration.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_configuration.tsx @@ -19,8 +19,8 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { SloSelector } from '../alerts/slo_selector'; import type { EmbeddableSloProps } from './types'; +import { SloSelector } from '../alerts/slo_selector'; interface SloConfigurationProps { onCreate: (props: EmbeddableSloProps) => void; @@ -29,14 +29,13 @@ interface SloConfigurationProps { export function SloConfiguration({ onCreate, onCancel }: SloConfigurationProps) { const [selectedSlo, setSelectedSlo] = useState(); + const [hasError, setHasError] = useState(false); const onConfirmClick = () => onCreate({ sloId: selectedSlo?.sloId, sloInstanceId: selectedSlo?.sloInstanceId, }); - const [hasError, setHasError] = useState(false); - return ( diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable.tsx deleted file mode 100644 index 9f1d9f5a9f003..0000000000000 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable.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 from 'react'; -import ReactDOM from 'react-dom'; -import { i18n } from '@kbn/i18n'; -import { Router } from '@kbn/shared-ux-router'; -import { - Embeddable as AbstractEmbeddable, - EmbeddableOutput, - IContainer, -} from '@kbn/embeddable-plugin/public'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { - type CoreStart, - IUiSettingsClient, - ApplicationStart, - NotificationsStart, -} from '@kbn/core/public'; -import { Subject } from 'rxjs'; -import { createBrowserHistory } from 'history'; -import type { SloErrorBudgetEmbeddableInput } from './types'; -import { SloErrorBudget } from './slo_error_budget_burn_down'; -export const SLO_ERROR_BUDGET_EMBEDDABLE = 'SLO_ERROR_BUDGET_EMBEDDABLE'; - -interface SloEmbeddableDeps { - uiSettings: IUiSettingsClient; - http: CoreStart['http']; - i18n: CoreStart['i18n']; - application: ApplicationStart; - notifications: NotificationsStart; -} - -export class SLOErrorBudgetEmbeddable extends AbstractEmbeddable< - SloErrorBudgetEmbeddableInput, - EmbeddableOutput -> { - public readonly type = SLO_ERROR_BUDGET_EMBEDDABLE; - private node?: HTMLElement; - private reloadSubject: Subject; - - constructor( - private readonly deps: SloEmbeddableDeps, - initialInput: SloErrorBudgetEmbeddableInput, - parent?: IContainer - ) { - super(initialInput, {}, parent); - this.reloadSubject = new Subject(); - - this.setTitle( - this.input.title || - i18n.translate('xpack.slo.sloErrorBudgetEmbeddable.displayTitle', { - defaultMessage: 'SLO Error Budget burn down', - }) - ); - } - - setTitle(title: string) { - this.updateInput({ title }); - } - - public onRenderComplete() { - this.renderComplete.dispatchComplete(); - } - - public render(node: HTMLElement) { - super.render(node); - this.node = node; - // required for the export feature to work - this.node.setAttribute('data-shared-item', ''); - - const { sloId, sloInstanceId } = this.getInput(); - const queryClient = new QueryClient(); - - const I18nContext = this.deps.i18n.Context; - ReactDOM.render( - - - - - - - - - , - node - ); - } - - public reload() { - this.reloadSubject.next(true); - } - - public destroy() { - super.destroy(); - if (this.node) { - ReactDOM.unmountComponentAtNode(this.node); - } - } -} diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable_factory.ts b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable_factory.ts deleted file mode 100644 index 8563d793a0913..0000000000000 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/slo_error_budget_embeddable_factory.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import type { CoreSetup } from '@kbn/core/public'; -import { - EmbeddableFactory, - EmbeddableFactoryDefinition, - ErrorEmbeddable, - IContainer, -} from '@kbn/embeddable-plugin/public'; -import { COMMON_SLO_GROUPING } from '../overview/slo_embeddable_factory'; -import { - SLO_ERROR_BUDGET_EMBEDDABLE, - SLOErrorBudgetEmbeddable, -} from './slo_error_budget_embeddable'; -import { SloPublicPluginsStart, SloPublicStart } from '../../..'; -import { SloErrorBudgetEmbeddableInput } from './types'; - -export type SloErrorBudgetEmbeddableFactory = EmbeddableFactory; -export class SloErrorBudgetEmbeddableFactoryDefinition implements EmbeddableFactoryDefinition { - public readonly type = SLO_ERROR_BUDGET_EMBEDDABLE; - - public readonly grouping = COMMON_SLO_GROUPING; - - constructor( - private getStartServices: CoreSetup['getStartServices'] - ) {} - - public async isEditable() { - return true; - } - - public async getExplicitInput(): Promise> { - const [coreStart, pluginStart] = await this.getStartServices(); - try { - const { resolveEmbeddableSloUserInput } = await import('./handle_explicit_input'); - return await resolveEmbeddableSloUserInput(coreStart, pluginStart); - } catch (e) { - return Promise.reject(); - } - } - - public async create(initialInput: SloErrorBudgetEmbeddableInput, parent?: IContainer) { - try { - const [coreStart, pluginsStart] = await this.getStartServices(); - const deps = { ...coreStart, ...pluginsStart }; - return new SLOErrorBudgetEmbeddable(deps, initialInput, parent); - } catch (e) { - return new ErrorEmbeddable(e, initialInput, parent); - } - } - - public getDescription() { - return i18n.translate('xpack.slo.sloErrorBudgetEmbeddable.description', { - defaultMessage: 'Get an error budget burn down chart of your SLOs', - }); - } - - public getDisplayName() { - return i18n.translate('xpack.slo.sloErrorBudgetEmbeddable.displayName', { - defaultMessage: 'SLO Error budget burn down', - }); - } - - public getIconType() { - return 'visLine'; - } -} diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/types.ts b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/types.ts index 66e862e64862c..83d2667f04b4c 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/types.ts +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/error_budget/types.ts @@ -4,8 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EmbeddableInput } from '@kbn/embeddable-plugin/public'; +import { + SerializedTitles, + PublishesWritablePanelTitle, + PublishesPanelTitle, +} from '@kbn/presentation-publishing'; +import { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; import { Subject } from 'rxjs'; +import { + type CoreStart, + IUiSettingsClient, + ApplicationStart, + NotificationsStart, +} from '@kbn/core/public'; export interface EmbeddableSloProps { sloId: string | undefined; @@ -13,4 +24,21 @@ export interface EmbeddableSloProps { reloadSubject?: Subject; onRenderComplete?: () => void; } -export type SloErrorBudgetEmbeddableInput = EmbeddableInput & EmbeddableSloProps; + +interface ErrorBudgetCustomInput { + sloId: string | undefined; + sloInstanceId: string | undefined; +} + +export type SloErrorBudgetEmbeddableState = SerializedTitles & ErrorBudgetCustomInput; +export type ErrorBudgetApi = DefaultEmbeddableApi & + PublishesWritablePanelTitle & + PublishesPanelTitle; + +export interface SloEmbeddableDeps { + uiSettings: IUiSettingsClient; + http: CoreStart['http']; + i18n: CoreStart['i18n']; + application: ApplicationStart; + notifications: NotificationsStart; +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx index 479998e36d539..11034718c9100 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx @@ -18,7 +18,7 @@ import { useKibana } from '../../../utils/kibana_react'; import { ChartData } from '../../../typings/slo'; import { ErrorBudgetChart } from './error_budget_chart'; import { ErrorBudgetHeader } from './error_budget_header'; -import { SLO_ERROR_BUDGET_EMBEDDABLE } from '../../../embeddable/slo/error_budget/slo_error_budget_embeddable'; +import { SLO_ERROR_BUDGET_ID } from '../../../embeddable/slo/error_budget/constants'; const SavedObjectSaveModalDashboard = withSuspense(LazySavedObjectSaveModalDashboard); export interface Props { data: ChartData[]; @@ -44,7 +44,7 @@ export function ErrorBudgetChartPanel({ data, isLoading, slo }: Props) { const state = { input: embeddableInput, - type: SLO_ERROR_BUDGET_EMBEDDABLE, + type: SLO_ERROR_BUDGET_ID, }; const path = dashboardId === 'new' ? '#/create' : `#/view/${dashboardId}`; diff --git a/x-pack/plugins/observability_solution/slo/public/plugin.ts b/x-pack/plugins/observability_solution/slo/public/plugin.ts index 285c85b06e78e..38bea63a1966c 100644 --- a/x-pack/plugins/observability_solution/slo/public/plugin.ts +++ b/x-pack/plugins/observability_solution/slo/public/plugin.ts @@ -15,6 +15,7 @@ import { PluginInitializerContext, } from '@kbn/core/public'; import { BehaviorSubject, firstValueFrom } from 'rxjs'; +import { registerReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; import { SloPublicPluginsSetup, SloPublicPluginsStart } from './types'; import { PLUGIN_NAME, sloAppId } from '../common'; import type { SloPublicSetup, SloPublicStart } from './types'; @@ -25,6 +26,7 @@ import { SLOS_BASE_PATH } from '../common/locators/paths'; import { getCreateSLOFlyoutLazy } from './pages/slo_edit/shared_flyout/get_create_slo_flyout'; import { registerBurnRateRuleType } from './rules/register_burn_rate_rule_type'; import { ExperimentalFeatures, SloConfig } from '../common/config'; +import { SLO_ERROR_BUDGET_ID } from './embeddable/slo/error_budget/constants'; export class SloPlugin implements Plugin @@ -111,22 +113,24 @@ export class SloPlugin }; registerSloAlertsEmbeddableFactory(); - const registerSloErrorBudgetEmbeddableFactory = async () => { - const { SloErrorBudgetEmbeddableFactoryDefinition } = await import( - './embeddable/slo/error_budget/slo_error_budget_embeddable_factory' + registerReactEmbeddableFactory(SLO_ERROR_BUDGET_ID, async () => { + const [coreStart, pluginsStart] = await coreSetup.getStartServices(); + + const deps = { ...coreStart, ...pluginsStart }; + + const { getErrorBudgetEmbeddableFactory } = await import( + './embeddable/slo/error_budget/error_budget_react_embeddable_factory' ); - const factory = new SloErrorBudgetEmbeddableFactoryDefinition(coreSetup.getStartServices); - pluginsSetup.embeddable.registerEmbeddableFactory(factory.type, factory); - }; - registerSloErrorBudgetEmbeddableFactory(); + return getErrorBudgetEmbeddableFactory(deps); + }); - const registerAsyncSloAlertsUiActions = async () => { + const registerAsyncSloUiActions = async () => { if (pluginsSetup.uiActions) { - const { registerSloAlertsUiActions } = await import('./ui_actions'); - registerSloAlertsUiActions(pluginsSetup.uiActions, coreSetup); + const { registerSloUiActions } = await import('./ui_actions'); + registerSloUiActions(pluginsSetup.uiActions, coreSetup); } }; - registerAsyncSloAlertsUiActions(); + registerAsyncSloUiActions(); } }; assertPlatinumLicense(); diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx new file mode 100644 index 0000000000000..40413846ce750 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import type { CoreSetup } from '@kbn/core/public'; +import { apiIsPresentationContainer } from '@kbn/presentation-containers'; +import { + IncompatibleActionError, + type UiActionsActionDefinition, +} from '@kbn/ui-actions-plugin/public'; +import { EmbeddableApiContext } from '@kbn/presentation-publishing'; +import { + ADD_SLO_ERROR_BUDGET_ACTION_ID, + SLO_ERROR_BUDGET_ID, +} from '../embeddable/slo/error_budget/constants'; +import { SloPublicPluginsStart, SloPublicStart } from '..'; +import { COMMON_SLO_GROUPING } from '../embeddable/slo/overview/slo_embeddable_factory'; +export function createAddErrorBudgetPanelAction( + getStartServices: CoreSetup['getStartServices'] +): UiActionsActionDefinition { + return { + id: ADD_SLO_ERROR_BUDGET_ACTION_ID, + grouping: COMMON_SLO_GROUPING, + getIconType: () => 'visLine', + isCompatible: async ({ embeddable }) => { + return apiIsPresentationContainer(embeddable); + }, + execute: async ({ embeddable }) => { + if (!apiIsPresentationContainer(embeddable)) throw new IncompatibleActionError(); + const [coreStart, deps] = await getStartServices(); + try { + const { openSloConfiguration } = await import( + '../embeddable/slo/error_budget/error_budget_open_configuration' + ); + const initialState = await openSloConfiguration(coreStart, deps); + embeddable.addNewPanel( + { + panelType: SLO_ERROR_BUDGET_ID, + initialState, + }, + true + ); + } catch (e) { + return Promise.reject(); + } + }, + getDisplayName: () => + i18n.translate('xpack.slo.errorBudgetEmbeddable.ariaLabel', { + defaultMessage: 'SLO Error Budget', + }), + }; +} diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts b/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts index 8ff601704e852..979c1e4cf6812 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts @@ -10,16 +10,20 @@ import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; import type { CoreSetup } from '@kbn/core/public'; import { createEditSloAlertsPanelAction } from './edit_slo_alerts_panel'; import { createEditSloOverviewPanelAction } from './edit_slo_overview_panel'; +import { createAddErrorBudgetPanelAction } from './create_error_budget_action'; import { SloPublicPluginsStart, SloPublicStart } from '..'; -export function registerSloAlertsUiActions( +export function registerSloUiActions( uiActions: UiActionsSetup, core: CoreSetup ) { // Initialize actions const editSloAlertsPanelAction = createEditSloAlertsPanelAction(core.getStartServices); const editSloOverviewPanelAction = createEditSloOverviewPanelAction(core.getStartServices); + const addErrorBudgetPanelAction = createAddErrorBudgetPanelAction(core.getStartServices); + // Assign triggers uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editSloAlertsPanelAction); uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editSloOverviewPanelAction); + uiActions.addTriggerAction('ADD_PANEL_TRIGGER', addErrorBudgetPanelAction); } diff --git a/x-pack/plugins/observability_solution/slo/tsconfig.json b/x-pack/plugins/observability_solution/slo/tsconfig.json index e25d212054699..b8a9c1d5e21b2 100644 --- a/x-pack/plugins/observability_solution/slo/tsconfig.json +++ b/x-pack/plugins/observability_solution/slo/tsconfig.json @@ -97,5 +97,6 @@ "@kbn/data-view-field-editor-plugin", "@kbn/securitysolution-io-ts-utils", "@kbn/core-elasticsearch-server-mocks", + "@kbn/presentation-containers", ] } From 2cc5109484ee8336b04bb52b4e58b0aa34480b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Zaffarano?= Date: Mon, 29 Apr 2024 16:02:51 -0300 Subject: [PATCH 010/104] [Security Solution][Telemetry] Add integration tests (#181927) --- .../__mocks__/endpoint-metrics.json | 2 +- .../server/integration_tests/lib/helpers.ts | 4 +- .../integration_tests/telemetry.test.ts | 471 +++++++++++++++- .../server/lib/telemetry/__mocks__/index.ts | 7 +- .../server/lib/telemetry/helpers.ts | 7 +- .../server/lib/telemetry/receiver.ts | 58 +- .../server/lib/telemetry/tasks/endpoint.ts | 502 +++++++++--------- .../server/lib/telemetry/telemetry_logger.ts | 23 +- 8 files changed, 770 insertions(+), 304 deletions(-) diff --git a/x-pack/plugins/security_solution/server/integration_tests/__mocks__/endpoint-metrics.json b/x-pack/plugins/security_solution/server/integration_tests/__mocks__/endpoint-metrics.json index cc3e0b03af31c..7ea0c4b023cd5 100644 --- a/x-pack/plugins/security_solution/server/integration_tests/__mocks__/endpoint-metrics.json +++ b/x-pack/plugins/security_solution/server/integration_tests/__mocks__/endpoint-metrics.json @@ -4,7 +4,7 @@ "build": { "original": "version: 8.6.0, compiled: Mon Jan 2 23:00:00 2023, branch: 8.6, commit: e2d09ff1b8e49bfb5f8940d317eb4ac96672d956" }, - "id": "123", + "id": "456", "type": "endpoint", "version": "8.6.0" }, diff --git a/x-pack/plugins/security_solution/server/integration_tests/lib/helpers.ts b/x-pack/plugins/security_solution/server/integration_tests/lib/helpers.ts index dadfdf79ebc9e..4cf1b69e0873a 100644 --- a/x-pack/plugins/security_solution/server/integration_tests/lib/helpers.ts +++ b/x-pack/plugins/security_solution/server/integration_tests/lib/helpers.ts @@ -22,8 +22,8 @@ const asyncUnlink = Util.promisify(Fs.unlink); */ export async function eventually( cb: () => Promise, - duration: number = 30000, - interval: number = 200 + duration: number = 60000, + interval: number = 1000 ) { let elapsed = 0; diff --git a/x-pack/plugins/security_solution/server/integration_tests/telemetry.test.ts b/x-pack/plugins/security_solution/server/integration_tests/telemetry.test.ts index 15b25a45c68c2..cdd984530d7aa 100644 --- a/x-pack/plugins/security_solution/server/integration_tests/telemetry.test.ts +++ b/x-pack/plugins/security_solution/server/integration_tests/telemetry.test.ts @@ -32,6 +32,7 @@ import { initEndpointIndices, dropEndpointIndices, mockEndpointData, + getTelemetryReceiver, } from './lib/telemetry_helpers'; import { @@ -47,6 +48,9 @@ import type { SecurityTelemetryTask } from '../lib/telemetry/task'; import { TelemetryChannel } from '../lib/telemetry/types'; import type { AsyncTelemetryEventsSender } from '../lib/telemetry/async_sender'; import endpointMetaTelemetryRequest from './__mocks__/endpoint-meta-telemetry-request.json'; +import type { ITelemetryReceiver, TelemetryReceiver } from '../lib/telemetry/receiver'; +import type { TaskMetric } from '../lib/telemetry/task_metrics.types'; +import type { AgentPolicy } from '@kbn/fleet-plugin/common'; jest.mock('axios'); @@ -57,6 +61,10 @@ const securitySolutionStartSpy = jest.spyOn(SecuritySolutionPlugin.prototype, 's const mockedAxiosGet = jest.spyOn(axios, 'get'); const mockedAxiosPost = jest.spyOn(axios, 'post'); +const securitySolutionPlugin = jest.spyOn(SecuritySolutionPlugin.prototype, 'start'); + +type Defer = () => void; + describe('telemetry tasks', () => { let esServer: TestElasticsearchUtils; let kibanaServer: TestKibanaUtils; @@ -66,6 +74,8 @@ describe('telemetry tasks', () => { let exceptionsList: ExceptionListSchema[] = []; let exceptionsListItem: ExceptionListItemSchema[] = []; let esClient: ElasticsearchClient; + let telemetryReceiver: ITelemetryReceiver; + let deferred: Defer[] = []; beforeAll(async () => { await removeFile(logFilePath); @@ -90,6 +100,9 @@ describe('telemetry tasks', () => { }); esClient = kibanaServer.coreStart.elasticsearch.client.asInternalUser; + + expect(securitySolutionPlugin).toHaveBeenCalledTimes(1); + telemetryReceiver = getTelemetryReceiver(securitySolutionPlugin); }); afterAll(async () => { @@ -104,6 +117,7 @@ describe('telemetry tasks', () => { beforeEach(async () => { jest.clearAllMocks(); mockAxiosGet(); + deferred = []; }); afterEach(async () => { @@ -120,6 +134,13 @@ describe('telemetry tasks', () => { exceptionsListItem = []; }); await cleanupMockedEndpointAlerts(kibanaServer.coreStart.elasticsearch.client.asInternalUser); + deferred.forEach((d) => { + try { + d(); + } catch (e) { + // ignore errors + } + }); }); describe('detection-rules', () => { @@ -143,14 +164,13 @@ describe('telemetry tasks', () => { it('should send task metrics', async () => { const task = await mockAndScheduleDetectionRulesTask(); + const started = performance.now(); - const requests = await getTaskMetricsRequests(task); + const requests = await getTaskMetricsRequests(task, started); expect(requests.length).toBeGreaterThan(0); - requests.forEach(({ body }) => { - const asJson = JSON.parse(body); - expect(asJson).not.toBeFalsy(); - expect(asJson.passed).toEqual(true); + requests.forEach((t) => { + expect(t.taskMetric.passed).toEqual(true); }); }); }); @@ -159,13 +179,14 @@ describe('telemetry tasks', () => { it('should use legacy sender by default', async () => { // launch a random task and verify it uses the new configuration const task = await mockAndScheduleDetectionRulesTask(); + const started = performance.now(); - const requests = await getTaskMetricsRequests(task); + const requests = await getTaskMetricsRequests(task, started); expect(requests.length).toBeGreaterThan(0); - requests.forEach(({ config }) => { - expect(config).not.toBeFalsy(); - if (config && config.headers) { - expect(config.headers['X-Telemetry-Sender']).not.toEqual('async'); + requests.forEach((r) => { + expect(r.requestConfig).not.toBeFalsy(); + if (r.requestConfig && r.requestConfig.headers) { + expect(r.requestConfig.headers['X-Telemetry-Sender']).not.toEqual('async'); } }); }); @@ -188,13 +209,14 @@ describe('telemetry tasks', () => { }); const task = await mockAndScheduleDetectionRulesTask(); + const started = performance.now(); - const requests = await getTaskMetricsRequests(task); + const requests = await getTaskMetricsRequests(task, started); expect(requests.length).toBeGreaterThan(0); - requests.forEach(({ config }) => { - expect(config).not.toBeFalsy(); - if (config && config.headers) { - expect(config.headers['X-Telemetry-Sender']).toEqual('async'); + requests.forEach((r) => { + expect(r.requestConfig).not.toBeFalsy(); + if (r.requestConfig && r.requestConfig.headers) { + expect(r.requestConfig.headers['X-Telemetry-Sender']).toEqual('async'); } }); }); @@ -260,23 +282,405 @@ describe('telemetry tasks', () => { it('should execute when scheduled', async () => { await mockAndScheduleEndpointTask(); - const body = await eventually(async () => { - const found = mockedAxiosPost.mock.calls.find(([url]) => { - return url.startsWith(ENDPOINT_STAGING) && url.endsWith(TELEMETRY_CHANNEL_ENDPOINT_META); - }); + const endpointMetaRequests = await getEndpointMetaRequests(); - expect(found).not.toBeFalsy(); + expect(endpointMetaRequests.length).toBe(2); - return JSON.parse((found ? found[1] : '{}') as string); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); + expect(body.policy_response).toStrictEqual(endpointMetaTelemetryRequest.policy_response); + }); + + it('should manage runtime errors searching endpoint metrics', async () => { + const fetchEndpointMetricsAbstract = telemetryReceiver.fetchEndpointMetricsAbstract; + deferred.push(() => { + telemetryReceiver.fetchEndpointMetricsAbstract = fetchEndpointMetricsAbstract; + }); + + const errorMessage = 'Something went wront'; + + telemetryReceiver.fetchEndpointMetricsAbstract = jest.fn((_) => + Promise.reject(Error(errorMessage)) + ); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(false); + expect(metric.taskMetric.error_message).toBe(errorMessage); + }); + + it('should manage runtime errors searching fleet agents', async () => { + const receiver: TelemetryReceiver = telemetryReceiver as TelemetryReceiver; + const agentClient = receiver['agentClient']!; + const listAgents = agentClient.listAgents; + deferred.push(() => { + agentClient.listAgents = listAgents; }); + const errorMessage = 'Error searching for fleet agents'; + + agentClient.listAgents = jest.fn((_) => Promise.reject(Error(errorMessage))); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual({}); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should work without fleet agents', async () => { + const receiver: TelemetryReceiver = telemetryReceiver as TelemetryReceiver; + const agentClient = receiver['agentClient']!; + const listAgents = agentClient.listAgents; + deferred.push(() => { + agentClient.listAgents = listAgents; + }); + + agentClient.listAgents = jest.fn((_) => + Promise.resolve({ + agents: [], + total: 0, + page: 0, + perPage: 0, + }) + ); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual({}); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + // expect(metric.error_message).toBe(errorMessage); + }); + + it('should manage runtime errors policy configs', async () => { + const errorMessage = 'Error getting policy configs'; + const fetchPolicyConfigs = telemetryReceiver.fetchPolicyConfigs; + deferred.push(() => { + telemetryReceiver.fetchPolicyConfigs = fetchPolicyConfigs; + }); + + telemetryReceiver.fetchPolicyConfigs = jest.fn((_) => Promise.reject(Error(errorMessage))); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual({}); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should manage unexpected errors dealing with policy configs', async () => { + const fetchPolicyConfigs = telemetryReceiver.fetchPolicyConfigs; + deferred.push(() => { + telemetryReceiver.fetchPolicyConfigs = fetchPolicyConfigs; + }); + + telemetryReceiver.fetchPolicyConfigs = jest.fn((_) => { + return Promise.resolve({ + package_policies: [ + { + invalid: 'value', + inputs: [ + { + unexpected: 'boom!', + }, + ], + }, + ], + } as unknown as AgentPolicy); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual({}); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should manage runtime errors fetching policy responses', async () => { + const errorMessage = 'Error getting policy responses'; + const fetchEndpointPolicyResponses = telemetryReceiver.fetchEndpointPolicyResponses; + deferred.push(() => { + telemetryReceiver.fetchEndpointPolicyResponses = fetchEndpointPolicyResponses; + }); + + telemetryReceiver.fetchEndpointPolicyResponses = jest.fn((_from, _to) => { + return Promise.reject(Error(errorMessage)); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should manage work with no policy responses', async () => { + const fetchEndpointPolicyResponses = telemetryReceiver.fetchEndpointPolicyResponses; + deferred.push(() => { + telemetryReceiver.fetchEndpointPolicyResponses = fetchEndpointPolicyResponses; + }); + + telemetryReceiver.fetchEndpointPolicyResponses = jest.fn((_from, _to) => { + return Promise.resolve(new Map()); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); + expect(body.policy_response).toStrictEqual({}); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should manage runtime errors fetching endpoint metadata', async () => { + const errorMessage = 'Error getting policy responses'; + const fetchEndpointMetadata = telemetryReceiver.fetchEndpointMetadata; + deferred.push(() => { + telemetryReceiver.fetchEndpointMetadata = fetchEndpointMetadata; + }); + + telemetryReceiver.fetchEndpointMetadata = jest.fn((_from, _to) => { + return Promise.reject(Error(errorMessage)); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual({ + ...endpointMetaTelemetryRequest.endpoint_meta, + capabilities: [], + }); + expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); + expect(body.policy_response).toStrictEqual(endpointMetaTelemetryRequest.policy_response); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should work with no endpoint metadata', async () => { + const fetchEndpointMetadata = telemetryReceiver.fetchEndpointMetadata; + deferred.push(() => { + telemetryReceiver.fetchEndpointMetadata = fetchEndpointMetadata; + }); + + telemetryReceiver.fetchEndpointMetadata = jest.fn((_from, _to) => { + return Promise.resolve(new Map()); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + expect(endpointMetaRequests.length).toBe(2); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual({ + ...endpointMetaTelemetryRequest.endpoint_meta, + capabilities: [], + }); expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); expect(body.policy_response).toStrictEqual(endpointMetaTelemetryRequest.policy_response); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); + }); + + it('should manage runtime errors fetching paginating endpoint metrics documents', async () => { + const receiver: TelemetryReceiver = telemetryReceiver as TelemetryReceiver; + const docsPerPage = receiver['docsPerPage']!; + const nextPage = receiver['nextPage']!; + deferred.push(() => { + receiver['docsPerPage'] = docsPerPage; + receiver['nextPage'] = nextPage; + }); + + // force to pull one doc at a time + receiver['docsPerPage'] = jest.fn((_index, _query) => { + return Promise.resolve(1); + }); + let pagesServed = 0; + receiver['nextPage'] = jest.fn(async (query) => { + // fail requesting the second doc + if (pagesServed++ >= 1) { + return Promise.reject(Error('Boom!')); + } + return esClient.search(query); + }); + + const task = await mockAndScheduleEndpointTask(); + const started = performance.now(); + + const endpointMetaRequests = await getEndpointMetaRequests(); + + // only one doc processed + expect(endpointMetaRequests.length).toBe(1); + const body = endpointMetaRequests[0]; + + expect(body.endpoint_metrics).toStrictEqual(endpointMetaTelemetryRequest.endpoint_metrics); + expect(body.endpoint_meta).toStrictEqual(endpointMetaTelemetryRequest.endpoint_meta); + expect(body.policy_config).toStrictEqual(endpointMetaTelemetryRequest.policy_config); + expect(body.policy_response).toStrictEqual(endpointMetaTelemetryRequest.policy_response); + + const requests = await getTaskMetricsRequests(task, started); + + expect(requests.length).toBe(1); + + const metric = requests[0]; + + expect(metric).not.toBeFalsy(); + expect(metric.taskMetric.passed).toBe(true); }); }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async function getEndpointMetaRequests(atLeast: number = 1): Promise { + return eventually(async () => { + const found = mockedAxiosPost.mock.calls.filter(([url]) => { + return url.startsWith(ENDPOINT_STAGING) && url.endsWith(TELEMETRY_CHANNEL_ENDPOINT_META); + }); + + expect(found).not.toBeFalsy(); + expect(found.length).toBeGreaterThanOrEqual(atLeast); + + return (found ?? []).flatMap((req) => { + const ndjson = req[1] as string; + return ndjson + .split('\n') + .filter((l) => l.trim().length > 0) + .map((l) => { + return JSON.parse(l); + }); + }); + }); + } + async function mockAndScheduleDetectionRulesTask(): Promise { const task = getTelemetryTask(tasks, 'security:telemetry-detection-rules'); @@ -327,6 +731,12 @@ describe('telemetry tasks', () => { } function mockAxiosGet(bufferConfig: unknown = fakeBufferAndSizesConfigAsyncDisabled) { + mockedAxiosPost.mockImplementation( + async (_url: string, _data?: unknown, _config?: AxiosRequestConfig | undefined) => { + return { status: 200 }; + } + ); + mockedAxiosGet.mockImplementation(async (url: string) => { if (url.startsWith(ENDPOINT_STAGING) && url.endsWith('ping')) { return { status: 200 }; @@ -345,11 +755,13 @@ describe('telemetry tasks', () => { }); } - async function getTaskMetricsRequests(task: SecurityTelemetryTask): Promise< + async function getTaskMetricsRequests( + task: SecurityTelemetryTask, + olderThan: number + ): Promise< Array<{ - url: string; - body: string; - config: AxiosRequestConfig | undefined; + taskMetric: TaskMetric; + requestConfig: AxiosRequestConfig | undefined; }> > { return eventually(async () => { @@ -367,7 +779,14 @@ describe('telemetry tasks', () => { ); }); expect(requests.length).toBeGreaterThan(0); - return requests; + return requests + .map((r) => { + return { + taskMetric: JSON.parse(r.body) as TaskMetric, + requestConfig: r.config, + }; + }) + .filter((t) => t.taskMetric.start_time >= olderThan); }); } }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts index bbdb08e481c48..e738815ac2553 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts @@ -117,20 +117,21 @@ export const createMockTelemetryReceiver = ( getClusterInfo: jest.fn().mockReturnValue(stubClusterInfo), fetchLicenseInfo: jest.fn().mockReturnValue(stubLicenseInfo), copyLicenseFields: jest.fn(), - fetchFleetAgents: jest.fn().mockReturnValue(stubFleetAgentResponse), + fetchPolicyConfigs: jest.fn().mockReturnValue(Promise.resolve(null)), + fetchFleetAgents: jest.fn().mockReturnValue(Promise.resolve(stubFleetAgentResponse)), openPointInTime: jest.fn().mockReturnValue(Promise.resolve('test-pit-id')), getAlertsIndex: jest.fn().mockReturnValue('alerts-*'), fetchDiagnosticAlertsBatch: jest.fn().mockReturnValue(diagnosticsAlert ?? jest.fn()), getExperimentalFeatures: jest.fn().mockReturnValue(undefined), fetchEndpointMetricsAbstract: jest.fn().mockReturnValue(stubEndpointMetricsAbstractResponse), fetchEndpointMetricsById: jest.fn().mockReturnValue(stubEndpointMetricsByIdResponse), - fetchEndpointPolicyResponses: jest.fn(), + fetchEndpointPolicyResponses: jest.fn().mockReturnValue(Promise.resolve(new Map())), fetchPrebuiltRuleAlertsBatch: jest.fn().mockReturnValue(prebuiltRuleAlertsResponse), fetchDetectionRulesPackageVersion: jest.fn(), fetchTrustedApplications: jest.fn(), fetchEndpointList: jest.fn(), fetchDetectionRules: jest.fn().mockReturnValue({ body: null }), - fetchEndpointMetadata: jest.fn(), + fetchEndpointMetadata: jest.fn().mockReturnValue(Promise.resolve(new Map())), fetchTimelineAlerts: jest.fn().mockReturnValue(Promise.resolve(stubEndpointAlertResponse())), buildProcessTree: jest.fn().mockReturnValue(processTreeResponse), fetchTimelineEvents: jest.fn().mockReturnValue(Promise.resolve(stubFetchTimelineEvents())), diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts index 7a4d71fc39853..d04731cf09f55 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts @@ -306,8 +306,11 @@ export const tlog = (logger: Logger, message: string, meta?: LogMeta) => { telemetryLogger(logger, message, meta); }; -export const newTelemetryLogger = (logger: Logger): TelemetryLogger => { - return new TelemetryLoggerImpl(logger); +export const newTelemetryLogger = ( + logger: Logger, + mdc?: LogMeta | object | undefined +): TelemetryLogger => { + return new TelemetryLoggerImpl(logger, mdc); }; function obfuscateString(clusterId: string, toHash: string): string { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts index 693892454cc56..eff642239da3a 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts @@ -53,8 +53,8 @@ import { exceptionListItemToTelemetryEntry, trustedApplicationToTelemetryEntry, ruleExceptionListItemToTelemetryEvent, - tlog, setClusterInfo, + newTelemetryLogger, } from './helpers'; import { Fetcher } from '../../endpoint/routes/resolver/tree/utils/fetch'; import type { TreeOptions, TreeResponse } from '../../endpoint/routes/resolver/tree/utils/fetch'; @@ -85,6 +85,7 @@ import { telemetryConfiguration } from './configuration'; import { ENDPOINT_METRICS_INDEX } from '../../../common/constants'; import { PREBUILT_RULES_PACKAGE_NAME } from '../../../common/detection_engine/constants'; import { DEFAULT_DIAGNOSTIC_INDEX } from './constants'; +import type { TelemetryLogger } from './telemetry_logger'; export interface ITelemetryReceiver { start( @@ -234,7 +235,7 @@ export interface ITelemetryReceiver { } export class TelemetryReceiver implements ITelemetryReceiver { - private readonly logger: Logger; + private readonly logger: TelemetryLogger; private agentClient?: AgentClient; private agentPolicyService?: AgentPolicyServiceInterface; private _esClient?: ElasticsearchClient; @@ -254,7 +255,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { private numDocsToSample: number = 10; constructor(logger: Logger) { - this.logger = logger.get('telemetry_events.receiver'); + this.logger = newTelemetryLogger(logger.get('telemetry_events.receiver')); } public async start( @@ -528,7 +529,10 @@ export class TelemetryReceiver implements ITelemetryReceiver { } public async *fetchDiagnosticAlertsBatch(executeFrom: string, executeTo: string) { - tlog(this.logger, `Searching diagnostic alerts from ${executeFrom} to ${executeTo}`); + this.logger.l('Searching diagnostic alerts', { + from: executeFrom, + to: executeTo, + }); let pitId = await this.openPointInTime(DEFAULT_DIAGNOSTIC_INDEX); let fetchMore = true; @@ -569,10 +573,10 @@ export class TelemetryReceiver implements ITelemetryReceiver { fetchMore = false; } - tlog(this.logger, `Diagnostic alerts to return: ${numOfHits}`); + this.logger.l('Diagnostic alerts to return', { numOfHits }); fetchMore = numOfHits > 0 && numOfHits < telemetryConfiguration.telemetry_max_buffer_size; } catch (e) { - tlog(this.logger, e); + this.logger.l('Error fetching alerts', { error: JSON.stringify(e) }); fetchMore = false; } @@ -741,7 +745,10 @@ export class TelemetryReceiver implements ITelemetryReceiver { } public async *fetchPrebuiltRuleAlertsBatch(executeFrom: string, executeTo: string) { - tlog(this.logger, `Searching prebuilt rule alerts from ${executeFrom} to ${executeTo}`); + this.logger.l('Searching prebuilt rule alerts from', { + executeFrom, + executeTo, + }); let pitId = await this.openPointInTime(DEFAULT_DIAGNOSTIC_INDEX); let fetchMore = true; @@ -876,14 +883,14 @@ export class TelemetryReceiver implements ITelemetryReceiver { pitId = response?.pit_id; } - tlog(this.logger, `Prebuilt rule alerts to return: ${alerts.length}`); + this.logger.l('Prebuilt rule alerts to return', { alerts: alerts.length }); yield alerts; } } catch (e) { // to keep backward compatibility with the previous implementation, silent return // once we start using `paginate` this error should be managed downstream - tlog(this.logger, e); + this.logger.l('Error fetching alerts', { error: JSON.stringify(e) }); return; } finally { await this.closePointInTime(pitId); @@ -907,7 +914,10 @@ export class TelemetryReceiver implements ITelemetryReceiver { try { await this.esClient().closePointInTime({ id: pitId }); } catch (error) { - tlog(this.logger, `Error trying to close point in time: "${pitId}". Error is: "${error}"`); + this.logger.l('Error trying to close point in time', { + pit: pitId, + error: JSON.stringify(error), + }); } } @@ -993,7 +1003,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { fetchMore = numOfHits > 0; } catch (e) { - tlog(this.logger, e); + this.logger.l('Error fetching alerts', { error: JSON.stringify(e) }); fetchMore = false; } @@ -1008,13 +1018,15 @@ export class TelemetryReceiver implements ITelemetryReceiver { try { await this.esClient().closePointInTime({ id: pitId }); } catch (error) { - tlog( - this.logger, - `Error trying to close point in time: "${pitId}", it will expire within "${keepAlive}". Error is: "${error}"` - ); + this.logger.l('Error trying to close point in time', { + pit: pitId, + error: JSON.stringify(error), + keepAlive, + }); } - tlog(this.logger, `Timeline alerts to return: ${alertsToReturn.length}`); + this.logger.l('Timeline alerts to return', { alerts: alertsToReturn.length }); + return alertsToReturn || []; } @@ -1202,7 +1214,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { return ret.license; } catch (err) { - tlog(this.logger, `failed retrieving license: ${err}`); + this.logger.l('failed retrieving license', { error: JSON.stringify(err) }); return undefined; } } @@ -1240,14 +1252,14 @@ export class TelemetryReceiver implements ITelemetryReceiver { const pit = { id: await this.openPointInTime(index), }; - const esQuery = { + const esQuery: ESSearchRequest = { ...cloneDeep(query), pit, size: Math.min(size, 10_000), }; try { do { - const response = await this.esClient().search(esQuery); + const response = await this.nextPage(esQuery); const hits = response?.hits.hits.length ?? 0; if (hits === 0) { @@ -1263,13 +1275,19 @@ export class TelemetryReceiver implements ITelemetryReceiver { yield data; } while (esQuery.search_after !== undefined); } catch (e) { - tlog(this.logger, `Error running paginated query: ${e}`); + this.logger.l('Error running paginated query', { error: JSON.stringify(e) }); throw e; } finally { await this.closePointInTime(pit.id); } } + private async nextPage( + esQuery: ESSearchRequest + ): Promise>> { + return this.esClient().search(esQuery); + } + public setMaxPageSizeBytes(bytes: number) { this.maxPageSizeBytes = bytes; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts index 8bd9aaecf7319..a55cbb4eda19a 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts @@ -13,11 +13,9 @@ import { TelemetryCounter, type EndpointMetadataDocument, type EndpointMetricDocument, - type EndpointMetricsAbstract, type EndpointPolicyResponseDocument, type ESClusterInfo, type ESLicense, - type FleetAgentResponse, type Nullable, } from '../types'; import type { ITelemetryReceiver } from '../receiver'; @@ -35,18 +33,14 @@ import { } from '../helpers'; import type { TelemetryLogger } from '../telemetry_logger'; import type { PolicyData } from '../../../../common/endpoint/types'; +import { telemetryConfiguration } from '../configuration'; import { TELEMETRY_CHANNEL_ENDPOINT_META } from '../constants'; -// Endpoint agent uses this Policy ID while it's installing. +/** + * Endpoint agent uses this Policy ID while it's installing. + */ const DefaultEndpointPolicyIdToIgnore = '00000000-0000-0000-0000-000000000000'; -const EmptyFleetAgentResponse: FleetAgentResponse = { - agents: [], - total: 0, - page: 0, - perPage: 0, -}; - const usageLabelPrefix: string[] = ['security_telemetry', 'endpoint_task']; export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { @@ -66,36 +60,16 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { taskMetricsService: ITaskMetricsService, taskExecutionPeriod: TaskExecutionPeriod ) => { - const log = newTelemetryLogger(logger.get('endpoint')); + const mdc = { task_id: taskId, task_execution_period: taskExecutionPeriod }; + const log = newTelemetryLogger(logger.get('endpoint'), mdc); const trace = taskMetricsService.start(taskType); - log.l( - `Running task: ${taskId} [last: ${taskExecutionPeriod.last} - current: ${taskExecutionPeriod.current}]` - ); + log.l('Running telemetry task'); try { - if (!taskExecutionPeriod.last) { - throw new Error('last execution timestamp is required'); - } + const processor = new EndpointMetadataProcessor(log, receiver); - const clusterData = await fetchClusterData(receiver); - - const endpointData = await fetchEndpointData( - receiver, - taskExecutionPeriod.last, - taskExecutionPeriod.current - ); - - /** - * STAGE 1 - Fetch Endpoint Agent Metrics - * If no metrics exist, then abort execution, otherwise increment - * the usage counter and continue. - */ - if (endpointData.endpointMetrics.totalEndpoints === 0) { - log.l('no endpoint metrics to report'); - taskMetricsService.end(trace); - return 0; - } + const documents = await processor.process(taskExecutionPeriod); const telemetryUsageCounter = sender.getTelemetryUsageCluster(); telemetryUsageCounter?.incrementCounter({ @@ -103,74 +77,30 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { usageLabelPrefix.concat(['payloads', TelemetryChannel.ENDPOINT_META]) ), counterType: TelemetryCounter.NUM_ENDPOINT, - incrementBy: endpointData.endpointMetrics.totalEndpoints, + incrementBy: documents.length, }); - /** - * STAGE 2 - * - Fetch Fleet Agent Config - * - Ignore policy used while installing the endpoint agent. - * - Fetch Endpoint Policy Configs - */ - const policyIdByAgent = endpointData.policyIdByAgent; - endpointData.policyIdByAgent.delete(DefaultEndpointPolicyIdToIgnore); - const endpointPolicyById = await endpointPolicies(policyIdByAgent.values(), receiver, log); - - /** - * STAGE 3 - Fetch Endpoint Policy Responses - */ - const policyResponses = endpointData.epPolicyResponse; - if (policyResponses.size === 0) { - log.l('no endpoint policy responses to report'); - } - - /** - * STAGE 4 - Fetch Endpoint Agent Metadata - */ - const endpointMetadata = endpointData.endpointMetadata; - if (endpointMetadata.size === 0) { - log.l(`no endpoint metadata to report`); - } - - /** STAGE 5 - Create the telemetry log records - * - * Iterates through the endpoint metrics documents at STAGE 1 and joins them together - * to form the telemetry log that is sent back to Elastic Security developers to - * make improvements to the product. - */ - const mappingContext = { - policyIdByAgent, - endpointPolicyById, - policyResponses, - endpointMetadata, - taskExecutionPeriod, - clusterData, - }; - const telemetryPayloads = []; - for await (const metrics of receiver.fetchEndpointMetricsById( - endpointData.endpointMetrics.endpointMetricIds - )) { - const payloads = metrics.map((endpointMetric) => - mapEndpointMetric(endpointMetric, mappingContext) - ); - telemetryPayloads.push(...payloads); - } - - log.l(`sending ${telemetryPayloads.length} endpoint telemetry records`); + log.l('Sending endpoint telemetry', { + num_docs: documents.length, + async_sender: telemetryConfiguration.use_async_sender, + }); - /** - * STAGE 6 - Send the documents - * - * Send the documents in a batches of maxTelemetryBatch - */ - const batches = batchTelemetryRecords(telemetryPayloads, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, batch); + // STAGE 6 - Send the documents + if (telemetryConfiguration.use_async_sender) { + sender.sendAsync(TelemetryChannel.ENDPOINT_META, documents); + } else { + const batches = batchTelemetryRecords(documents, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, batch); + } } taskMetricsService.end(trace); - return telemetryPayloads.length; + + return documents.length; } catch (err) { - log.warn(`could not complete endpoint alert telemetry task due to ${err?.message}`, err); + log.l(`Error running endpoint alert telemetry task`, { + error: JSON.stringify(err), + }); taskMetricsService.end(trace, err); return 0; } @@ -178,169 +108,259 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { }; } -async function fetchEndpointData( - receiver: ITelemetryReceiver, - executeFrom: string, - executeTo: string -): Promise<{ - policyIdByAgent: Map; - endpointMetrics: EndpointMetricsAbstract; - epPolicyResponse: Map; - endpointMetadata: Map; -}> { - const [policyIdByAgent, epMetricsAbstractResponse, policyResponse, endpointMetadata] = - await Promise.allSettled([ - receiver.fetchFleetAgents(), - receiver.fetchEndpointMetricsAbstract(executeFrom, executeTo), - receiver.fetchEndpointPolicyResponses(executeFrom, executeTo), - receiver.fetchEndpointMetadata(executeFrom, executeTo), - ]); +class EndpointMetadataProcessor { + private readonly logger: TelemetryLogger; - return { - policyIdByAgent: safeValue(policyIdByAgent, EmptyFleetAgentResponse), - endpointMetrics: safeValue(epMetricsAbstractResponse), - epPolicyResponse: safeValue(policyResponse), - endpointMetadata: safeValue(endpointMetadata), - }; -} + constructor(logger: Logger, private readonly receiver: ITelemetryReceiver) { + this.logger = newTelemetryLogger(logger.get('processor')); + } -async function fetchClusterData( - receiver: ITelemetryReceiver -): Promise<{ clusterInfo: ESClusterInfo; licenseInfo: Nullable }> { - const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ - receiver.fetchClusterInfo(), - receiver.fetchLicenseInfo(), - ]); + public async process(taskExecutionPeriod: TaskExecutionPeriod): Promise { + const last = taskExecutionPeriod.last; + const current = taskExecutionPeriod.current; - const clusterInfo = safeValue(clusterInfoPromise); - const licenseInfo = safeValue(licenseInfoPromise); + if (!last) { + throw new Error('last execution timestamp is required'); + } - return { clusterInfo, licenseInfo }; -} + // STAGE 1 - Fetch Endpoint Agent Metrics + const endpointMetrics = await this.receiver.fetchEndpointMetricsAbstract(last, current); + // If no metrics exist, early (and successfull) exit + if (endpointMetrics.totalEndpoints === 0) { + this.logger.l('no endpoint metrics to report'); + return []; + } -async function endpointPolicies( - policyIds: IterableIterator, - receiver: ITelemetryReceiver, - log: TelemetryLogger -) { - const endpointPolicyCache = new Map(); - for (const policyId of policyIds) { - if (policyId !== null && policyId !== undefined && !endpointPolicyCache.has(policyId)) { - const agentPolicy = await receiver.fetchPolicyConfigs(policyId).catch((e) => { - log.l(`error fetching policy config due to ${e?.message}`); - return null; + /** + * STAGE 2 + * - Fetch Fleet Agent Config + * - Ignore policy used while installing the endpoint agent. + * - Fetch Endpoint Policy Configs + */ + const policyIdByFleetAgentId = await this.receiver + .fetchFleetAgents() + .then((policies) => { + policies.delete(DefaultEndpointPolicyIdToIgnore); + return policies; + }) + .catch((e) => { + this.logger.l('Error fetching fleet agents, using an empty value', { + error: JSON.stringify(e), + }); + return new Map(); }); + const endpointPolicyById = await this.endpointPolicies(policyIdByFleetAgentId.values()); - const packagePolicies = agentPolicy?.package_policies; - - if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { - packagePolicies - .map((pPolicy) => pPolicy as PolicyData) - .forEach((pPolicy) => { - if (pPolicy.inputs[0]?.config !== undefined && pPolicy.inputs[0]?.config !== null) { - pPolicy.inputs.forEach((input) => { - if ( - input.type === FLEET_ENDPOINT_PACKAGE && - input?.config !== undefined && - policyId !== undefined - ) { - endpointPolicyCache.set(policyId, pPolicy); - } - }); - } - }); + /** + * STAGE 3 - Fetch Endpoint Policy Responses + */ + const policyResponses = await this.receiver + .fetchEndpointPolicyResponses(last, current) + .then((response) => { + if (response.size === 0) { + this.logger.l('no endpoint policy responses to report'); + } + return response; + }) + .catch((e) => { + this.logger.l('Error fetching policy responses, using an empty value', { + error: JSON.stringify(e), + }); + return new Map(); + }); + + /** + * STAGE 4 - Fetch Endpoint Agent Metadata + */ + const endpointMetadata = await this.receiver + .fetchEndpointMetadata(last, current) + .then((response) => { + if (response.size === 0) { + this.logger.l('no endpoint metadata to report'); + } + return response; + }) + .catch((e) => { + this.logger.l('Error fetching endpoint metadata, using an empty value', { + error: JSON.stringify(e), + }); + return new Map(); + }); + + /** STAGE 5 - Create the telemetry log records + * + * Iterates through the endpoint metrics documents at STAGE 1 and joins them together + * to form the telemetry log that is sent back to Elastic Security developers to + * make improvements to the product. + */ + const clusterData = await this.fetchClusterData(); + const mappingContext = { + policyIdByFleetAgentId, + endpointPolicyById, + policyResponses, + endpointMetadata, + taskExecutionPeriod, + clusterData, + }; + const telemetryPayloads: object[] = []; + try { + for await (const metrics of this.receiver.fetchEndpointMetricsById( + endpointMetrics.endpointMetricIds + )) { + const payloads = metrics.map((endpointMetric) => + this.mapEndpointMetric(endpointMetric, mappingContext) + ); + telemetryPayloads.push(...payloads); } + } catch (e) { + // something happened in the middle of the pagination, log the error + // and return what we collect so far instead of aborting the + // whole execution + this.logger.l('Error fetching endpoint metrics by id', { + error: JSON.stringify(e), + }); } + + return telemetryPayloads; } - return endpointPolicyCache; -} -function mapEndpointMetric( - endpointMetric: EndpointMetricDocument, - ctx: { - policyIdByAgent: Map; - endpointPolicyById: Map; - policyResponses: Map; - endpointMetadata: Map; - taskExecutionPeriod: TaskExecutionPeriod; - clusterData: { clusterInfo: ESClusterInfo; licenseInfo: Nullable }; + private async fetchClusterData(): Promise<{ + clusterInfo: ESClusterInfo; + licenseInfo: Nullable; + }> { + const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ + this.receiver.fetchClusterInfo(), + this.receiver.fetchLicenseInfo(), + ]); + + const clusterInfo = safeValue(clusterInfoPromise); + const licenseInfo = safeValue(licenseInfoPromise); + + return { clusterInfo, licenseInfo }; } -) { - let policyConfig = null; - let failedPolicy: Nullable = null; - let endpointMetadataById = null; - const fleetAgentId = endpointMetric.elastic.agent.id; - const endpointAgentId = endpointMetric.agent.id; + private async endpointPolicies(policies: IterableIterator) { + const endpointPolicyCache = new Map(); + for (const policyId of policies) { + if (!endpointPolicyCache.has(policyId)) { + const agentPolicy = await this.receiver.fetchPolicyConfigs(policyId).catch((e) => { + this.logger.l(`error fetching policy config due to ${e?.message}`); + return null; + }); - const policyId = ctx.policyIdByAgent.get(fleetAgentId); - if (policyId) { - policyConfig = ctx.endpointPolicyById.get(policyId) || null; + const packagePolicies = agentPolicy?.package_policies; - if (policyConfig) { - failedPolicy = ctx.policyResponses.get(endpointAgentId); + if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { + packagePolicies + .map((pPolicy) => pPolicy as PolicyData) + .forEach((pPolicy) => { + if (pPolicy.inputs[0]?.config !== undefined && pPolicy.inputs[0]?.config !== null) { + pPolicy.inputs.forEach((input) => { + if ( + input.type === FLEET_ENDPOINT_PACKAGE && + input?.config !== undefined && + policyId !== undefined + ) { + endpointPolicyCache.set(policyId, pPolicy); + } + }); + } + }); + } + } } + return endpointPolicyCache; } - if (ctx.endpointMetadata) { - endpointMetadataById = ctx.endpointMetadata.get(endpointAgentId); - } + private mapEndpointMetric( + endpointMetric: EndpointMetricDocument, + ctx: { + policyIdByFleetAgentId: Map; + endpointPolicyById: Map; + policyResponses: Map; + endpointMetadata: Map; + taskExecutionPeriod: TaskExecutionPeriod; + clusterData: { clusterInfo: ESClusterInfo; licenseInfo: Nullable }; + } + ) { + let policyConfig = null; + let failedPolicy: Nullable = null; + let endpointMetadataById = null; - const { - cpu, - memory, - uptime, - documents_volume: documentsVolume, - malicious_behavior_rules: maliciousBehaviorRules, - system_impact: systemImpact, - threads, - event_filter: eventFilter, - } = endpointMetric.Endpoint.metrics; - const endpointPolicyDetail = extractEndpointPolicyConfig(policyConfig); - if (endpointPolicyDetail) { - endpointPolicyDetail.value = addDefaultAdvancedPolicyConfigSettings(endpointPolicyDetail.value); - } - return { - '@timestamp': ctx.taskExecutionPeriod.current, - cluster_uuid: ctx.clusterData.clusterInfo.cluster_uuid, - cluster_name: ctx.clusterData.clusterInfo.cluster_name, - license_id: ctx.clusterData.licenseInfo?.uid, - endpoint_id: endpointAgentId, - endpoint_version: endpointMetric.agent.version, - endpoint_package_version: policyConfig?.package?.version || null, - endpoint_metrics: { - cpu: cpu.endpoint, - memory: memory.endpoint.private, + const fleetAgentId = endpointMetric.elastic.agent.id; + const endpointAgentId = endpointMetric.agent.id; + + const policyId = ctx.policyIdByFleetAgentId.get(fleetAgentId); + if (policyId) { + policyConfig = ctx.endpointPolicyById.get(policyId) || null; + + if (policyConfig) { + failedPolicy = ctx.policyResponses.get(endpointAgentId); + } + } + + if (ctx.endpointMetadata) { + endpointMetadataById = ctx.endpointMetadata.get(endpointAgentId); + } + + const { + cpu, + memory, uptime, - documentsVolume, - maliciousBehaviorRules, - systemImpact, + documents_volume: documentsVolume, + malicious_behavior_rules: maliciousBehaviorRules, + system_impact: systemImpact, threads, - eventFilter, - }, - endpoint_meta: { - os: endpointMetric.host.os, - capabilities: - endpointMetadataById !== null && endpointMetadataById !== undefined - ? endpointMetadataById.Endpoint.capabilities - : [], - }, - policy_config: endpointPolicyDetail !== null ? endpointPolicyDetail : {}, - policy_response: - failedPolicy !== null && failedPolicy !== undefined - ? { - agent_policy_status: failedPolicy.event.agent_id_status, - manifest_version: failedPolicy.Endpoint.policy.applied.artifacts.global.version, - status: failedPolicy.Endpoint.policy.applied.status, - actions: failedPolicy.Endpoint.policy.applied.actions - .map((action) => (action.status !== 'success' ? action : null)) - .filter((action) => action !== null), - configuration: failedPolicy.Endpoint.configuration, - state: failedPolicy.Endpoint.state, - } - : {}, - telemetry_meta: { - metrics_timestamp: endpointMetric['@timestamp'], - }, - }; + event_filter: eventFilter, + } = endpointMetric.Endpoint.metrics; + const endpointPolicyDetail = extractEndpointPolicyConfig(policyConfig); + if (endpointPolicyDetail) { + endpointPolicyDetail.value = addDefaultAdvancedPolicyConfigSettings( + endpointPolicyDetail.value + ); + } + return { + '@timestamp': ctx.taskExecutionPeriod.current, + cluster_uuid: ctx.clusterData.clusterInfo.cluster_uuid, + cluster_name: ctx.clusterData.clusterInfo.cluster_name, + license_id: ctx.clusterData.licenseInfo?.uid, + endpoint_id: endpointAgentId, + endpoint_version: endpointMetric.agent.version, + endpoint_package_version: policyConfig?.package?.version || null, + endpoint_metrics: { + cpu: cpu.endpoint, + memory: memory.endpoint.private, + uptime, + documentsVolume, + maliciousBehaviorRules, + systemImpact, + threads, + eventFilter, + }, + endpoint_meta: { + os: endpointMetric.host.os, + capabilities: + endpointMetadataById !== null && endpointMetadataById !== undefined + ? endpointMetadataById.Endpoint.capabilities + : [], + }, + policy_config: endpointPolicyDetail !== null ? endpointPolicyDetail : {}, + policy_response: + failedPolicy !== null && failedPolicy !== undefined + ? { + agent_policy_status: failedPolicy.event.agent_id_status, + manifest_version: failedPolicy.Endpoint.policy.applied.artifacts.global.version, + status: failedPolicy.Endpoint.policy.applied.status, + actions: failedPolicy.Endpoint.policy.applied.actions + .map((action) => (action.status !== 'success' ? action : null)) + .filter((action) => action !== null), + configuration: failedPolicy.Endpoint.configuration, + state: failedPolicy.Endpoint.state, + } + : {}, + telemetry_meta: { + metrics_timestamp: endpointMetric['@timestamp'], + }, + }; + } } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/telemetry_logger.ts b/x-pack/plugins/security_solution/server/lib/telemetry/telemetry_logger.ts index b457cea89d36e..1876608a91b52 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/telemetry_logger.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/telemetry_logger.ts @@ -33,7 +33,10 @@ export interface TelemetryLogger extends Logger { * It makes easier to browse the logs by filtering by the structured argument `logger`. */ export class TelemetryLoggerImpl implements TelemetryLogger { - constructor(private readonly delegate: Logger) {} + constructor( + private readonly delegate: Logger, + private readonly mdc?: LogMeta | object | undefined + ) {} l(message: string, meta?: Meta | object | undefined): void { if (isElasticCloudDeployment) { @@ -44,27 +47,27 @@ export class TelemetryLoggerImpl implements TelemetryLogger { } trace(message: string, meta?: Meta): void { - this.delegate.trace(message, logMeta(meta)); + this.delegate.trace(message, logMeta(meta, this.mdc)); } debug(message: string, meta?: Meta): void { - this.delegate.debug(message, logMeta(meta)); + this.delegate.debug(message, logMeta(meta, this.mdc)); } info(message: string, meta?: Meta): void { - this.delegate.info(message, logMeta(meta)); + this.delegate.info(message, logMeta(meta, this.mdc)); } warn(errorOrMessage: string | Error, meta?: Meta): void { - this.delegate.warn(errorOrMessage, logMeta(meta)); + this.delegate.warn(errorOrMessage, logMeta(meta, this.mdc)); } error(errorOrMessage: string | Error, meta?: Meta): void { - this.delegate.error(errorOrMessage, logMeta(meta)); + this.delegate.error(errorOrMessage, logMeta(meta, this.mdc)); } fatal(errorOrMessage: string | Error, meta?: Meta): void { - this.delegate.fatal(errorOrMessage, logMeta(meta)); + this.delegate.fatal(errorOrMessage, logMeta(meta, this.mdc)); } log(record: LogRecord): void { @@ -76,7 +79,8 @@ export class TelemetryLoggerImpl implements TelemetryLogger { } get(...childContextPaths: string[]): Logger { - return this.delegate.get(...childContextPaths); + const logger = this.delegate.get(...childContextPaths); + return new TelemetryLoggerImpl(logger, this.mdc); } } @@ -89,7 +93,7 @@ export const tlog = (logger: Logger, message: string, meta?: LogMeta) => { }; // helper method to merge a given LogMeta with the cluster info (if exists) -function logMeta(meta?: LogMeta | undefined): LogMeta { +function logMeta(meta?: LogMeta | undefined, mdc?: LogMeta | undefined): LogMeta { const clusterInfoMeta = clusterInfo ? { cluster_uuid: clusterInfo?.cluster_uuid, @@ -99,5 +103,6 @@ function logMeta(meta?: LogMeta | undefined): LogMeta { return { ...clusterInfoMeta, ...(meta ?? {}), + ...(mdc ?? {}), }; } From 102c2070251e812dafb512f1518858886fc8d750 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Mon, 29 Apr 2024 15:28:48 -0400 Subject: [PATCH 011/104] [Embeddables Rebuild] Example aesthetics (#181920) Slight aesthetic changes to the example embeddables --- .../data_table/create_data_table_action.ts | 4 +- ...ing.ts => embeddable_examples_grouping.ts} | 3 +- .../create_eui_markdown_action.tsx | 4 +- .../field_list/create_field_list_action.tsx | 4 +- .../register_add_search_panel_action.tsx | 4 +- .../search/search_react_embeddable.tsx | 73 +++++++++++++------ 6 files changed, 59 insertions(+), 33 deletions(-) rename examples/embeddable_examples/public/react_embeddables/{add_panel_grouping.ts => embeddable_examples_grouping.ts} (84%) diff --git a/examples/embeddable_examples/public/react_embeddables/data_table/create_data_table_action.ts b/examples/embeddable_examples/public/react_embeddables/data_table/create_data_table_action.ts index 3d0c99289b121..9971535e148dd 100644 --- a/examples/embeddable_examples/public/react_embeddables/data_table/create_data_table_action.ts +++ b/examples/embeddable_examples/public/react_embeddables/data_table/create_data_table_action.ts @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { apiIsPresentationContainer } from '@kbn/presentation-containers'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public'; -import { addPanelGrouping } from '../add_panel_grouping'; +import { embeddableExamplesGrouping } from '../embeddable_examples_grouping'; import { ADD_DATA_TABLE_ACTION_ID, DATA_TABLE_ID } from './constants'; // ----------------------------------------------------------------------------- @@ -20,7 +20,7 @@ import { ADD_DATA_TABLE_ACTION_ID, DATA_TABLE_ID } from './constants'; export const registerCreateDataTableAction = (uiActions: UiActionsStart) => { uiActions.registerAction({ id: ADD_DATA_TABLE_ACTION_ID, - grouping: [addPanelGrouping], + grouping: [embeddableExamplesGrouping], getIconType: () => 'tableDensityNormal', isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); diff --git a/examples/embeddable_examples/public/react_embeddables/add_panel_grouping.ts b/examples/embeddable_examples/public/react_embeddables/embeddable_examples_grouping.ts similarity index 84% rename from examples/embeddable_examples/public/react_embeddables/add_panel_grouping.ts rename to examples/embeddable_examples/public/react_embeddables/embeddable_examples_grouping.ts index 2c043569d5cfb..fa2ecd03b5d25 100644 --- a/examples/embeddable_examples/public/react_embeddables/add_panel_grouping.ts +++ b/examples/embeddable_examples/public/react_embeddables/embeddable_examples_grouping.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -export const addPanelGrouping = { +export const embeddableExamplesGrouping = { id: 'embeddableExamples', + getIconType: () => 'documentation', getDisplayName: () => 'Embeddable examples', }; diff --git a/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx b/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx index cd95ba582d2d1..81c23a4d960b8 100644 --- a/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/eui_markdown/create_eui_markdown_action.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { apiCanAddNewPanel } from '@kbn/presentation-containers'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public'; -import { addPanelGrouping } from '../add_panel_grouping'; +import { embeddableExamplesGrouping } from '../embeddable_examples_grouping'; import { ADD_EUI_MARKDOWN_ACTION_ID, EUI_MARKDOWN_ID } from './constants'; import { MarkdownEditorSerializedState } from './types'; @@ -21,7 +21,7 @@ import { MarkdownEditorSerializedState } from './types'; export const registerCreateEuiMarkdownAction = (uiActions: UiActionsStart) => { uiActions.registerAction({ id: ADD_EUI_MARKDOWN_ACTION_ID, - grouping: [addPanelGrouping], + grouping: [embeddableExamplesGrouping], getIconType: () => 'editorCodeBlock', isCompatible: async ({ embeddable }) => { return apiCanAddNewPanel(embeddable); diff --git a/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx b/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx index 7aa799a55f6e2..e05868e7737d1 100644 --- a/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/field_list/create_field_list_action.tsx @@ -11,14 +11,14 @@ import { apiCanAddNewPanel } from '@kbn/presentation-containers'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; +import { embeddableExamplesGrouping } from '../embeddable_examples_grouping'; import { ADD_FIELD_LIST_ACTION_ID, FIELD_LIST_ID } from './constants'; import { FieldListSerializedStateState } from './types'; -import { addPanelGrouping } from '../add_panel_grouping'; export const registerCreateFieldListAction = (uiActions: UiActionsPublicStart) => { uiActions.registerAction({ id: ADD_FIELD_LIST_ACTION_ID, - grouping: [addPanelGrouping], + grouping: [embeddableExamplesGrouping], getIconType: () => 'indexOpen', isCompatible: async ({ embeddable }) => { return apiCanAddNewPanel(embeddable); diff --git a/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx b/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx index cb20f288bf032..18bd40fe69dae 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx +++ b/examples/embeddable_examples/public/react_embeddables/search/register_add_search_panel_action.tsx @@ -9,14 +9,14 @@ import { apiCanAddNewPanel } from '@kbn/presentation-containers'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { IncompatibleActionError, UiActionsStart } from '@kbn/ui-actions-plugin/public'; -import { addPanelGrouping } from '../add_panel_grouping'; +import { embeddableExamplesGrouping } from '../embeddable_examples_grouping'; import { ADD_SEARCH_ACTION_ID, SEARCH_EMBEDDABLE_ID } from './constants'; import { SearchSerializedState } from './types'; export const registerAddSearchPanelAction = (uiActions: UiActionsStart) => { uiActions.registerAction({ id: ADD_SEARCH_ACTION_ID, - grouping: [addPanelGrouping], + grouping: [embeddableExamplesGrouping], getDisplayName: () => 'Search example', getIconType: () => 'search', isCompatible: async ({ embeddable }) => { diff --git a/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx b/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx index 3664c1cb4a411..2b789a17da4ae 100644 --- a/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx +++ b/examples/embeddable_examples/public/react_embeddables/search/search_react_embeddable.tsx @@ -6,14 +6,17 @@ * Side Public License, v 1. */ -import { EuiCallOut } from '@elastic/eui'; +import { EuiBadge, EuiStat } from '@elastic/eui'; +import { css } from '@emotion/react'; import { DataView } from '@kbn/data-views-plugin/common'; import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; +import { i18n } from '@kbn/i18n'; import { - initializeTimeRange, fetch$, + initializeTimeRange, useBatchedPublishingSubjects, } from '@kbn/presentation-publishing'; +import { euiThemeVars } from '@kbn/ui-theme'; import React, { useEffect } from 'react'; import { BehaviorSubject, switchMap, tap } from 'rxjs'; import { SEARCH_EMBEDDABLE_ID } from './constants'; @@ -31,10 +34,22 @@ export const getSearchEmbeddableFactory = (services: Services) => { defaultDataView ? [defaultDataView] : undefined ); const dataLoading$ = new BehaviorSubject(false); + const blockingError$ = new BehaviorSubject(undefined); + + if (!defaultDataView) { + blockingError$.next( + new Error( + i18n.translate('embeddableExamples.search.noDataViewError', { + defaultMessage: 'Please install a data view to view this example', + }) + ) + ); + } const api = buildApi( { ...timeRange.api, + blockingError: blockingError$, dataViews: dataViews$, dataLoading: dataLoading$, serializeState: () => { @@ -51,7 +66,6 @@ export const getSearchEmbeddableFactory = (services: Services) => { } ); - const error$ = new BehaviorSubject(undefined); const count$ = new BehaviorSubject(0); let prevRequestAbortController: AbortController | undefined; const fetchSubscription = fetch$(api) @@ -62,7 +76,7 @@ export const getSearchEmbeddableFactory = (services: Services) => { } }), switchMap(async (fetchContext) => { - error$.next(undefined); + blockingError$.next(undefined); if (!defaultDataView) { return; } @@ -101,14 +115,14 @@ export const getSearchEmbeddableFactory = (services: Services) => { count$.next(next.count); } if (next && next.hasOwnProperty('error')) { - error$.next(next.error); + blockingError$.next(next.error); } }); return { api, Component: () => { - const [count, error] = useBatchedPublishingSubjects(count$, error$); + const [count, error] = useBatchedPublishingSubjects(count$, blockingError$); useEffect(() => { return () => { @@ -116,26 +130,37 @@ export const getSearchEmbeddableFactory = (services: Services) => { }; }, []); - if (!defaultDataView) { - return ( - -

    Please install a sample data set to run example.

    -
    - ); - } - - if (error) { - return ( - -

    {error.message}

    -
    - ); - } + // in error case we can return null because the panel will handle rendering the blocking error. + if (error || !defaultDataView) return null; return ( -

    - Found {count} from {defaultDataView.name} -

    +
    + + + {i18n.translate('embeddableExamples.search.dataViewName', { + defaultMessage: '{dataViewName}', + values: { dataViewName: defaultDataView.name }, + })} + + + } + titleSize="l" + > + {i18n.translate('embeddableExamples.search.result', { + defaultMessage: '{count, plural, one {document} other {documents}} found', + values: { count }, + })} + +
    ); }, }; From ffcd25475dd9cd4b6e99103a244fea1db64054af Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Mon, 29 Apr 2024 14:57:16 -0500 Subject: [PATCH 012/104] [Detection Engine] Re-skip machine learning FTR tests (#182022) There's a failure caused when test data is loaded that does not happen in isolation, and we just had another [occurrence](https://buildkite.com/elastic/kibana-on-merge/builds/44452#018f2a90-2ee6-4384-9abe-1b5b78cfac79). I need to figure out where that's coming from before these can be unskipped. --- .../execution_logic/machine_learning.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts index 2044a543844f7..3fb077df86a38 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts @@ -86,7 +86,8 @@ export default ({ getService }: FtrProviderContext) => { rule_id: 'ml-rule-id', }; - describe('@ess @serverless @serverlessQA Machine learning type rules', () => { + // FLAKY: https://github.com/elastic/kibana/issues/171426 + describe.skip('@ess @serverless @serverlessQA Machine learning type rules', () => { before(async () => { // Order is critical here: auditbeat data must be loaded before attempting to start the ML job, // as the job looks for certain indices on start From beef46beb429a41ff14e980ed8bf2b1032b76d95 Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Mon, 29 Apr 2024 15:00:04 -0500 Subject: [PATCH 013/104] [Security Solution][Alert details] - use expandable flyout within timeline Notes (#181497) --- .../document_details/isolate_host/index.tsx | 3 +- .../flyout/document_details/left/index.tsx | 2 +- .../flyout/document_details/preview/index.tsx | 3 +- .../flyout/document_details/right/footer.tsx | 3 +- .../flyout/document_details/right/index.tsx | 2 +- .../shared/constants/panel_keys.ts | 14 ++-- .../open_timeline/note_previews/index.tsx | 64 +++++++++++++++---- .../event_details/expandable_event.tsx | 3 +- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/index.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/index.tsx index 7d9d682b1fe0a..308a71fdf2430 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/index.tsx @@ -8,11 +8,12 @@ import type { FC } from 'react'; import React from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; +import type { DocumentDetailsIsolateHostPanelKey } from '../shared/constants/panel_keys'; import { PanelContent } from './content'; import { PanelHeader } from './header'; export interface IsolateHostPanelProps extends FlyoutPanelProps { - key: 'document-details-isolate-host'; + key: typeof DocumentDetailsIsolateHostPanelKey; params?: { id: string; indexName: string; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/index.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/index.tsx index fc644c99e297c..84e9d2553a422 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/index.tsx @@ -27,7 +27,7 @@ export const LeftPanelInvestigationTab: LeftPanelPaths = 'investigation'; export const LeftPanelResponseTab: LeftPanelPaths = 'response'; export interface LeftPanelProps extends FlyoutPanelProps { - key: 'document-details-left'; + key: typeof DocumentDetailsLeftPanelKey; path?: PanelPath; params?: { id: string; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/preview/index.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/preview/index.tsx index 1d0080f795d80..27e7d8646031c 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/preview/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/preview/index.tsx @@ -8,6 +8,7 @@ import React, { memo, useMemo } from 'react'; import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import type { DocumentDetailsPreviewPanelKey } from '../shared/constants/panel_keys'; import { panels } from './panels'; export type PreviewPanelPaths = 'rule-preview' | 'alert-reason-preview'; @@ -15,7 +16,7 @@ export const RulePreviewPanel: PreviewPanelPaths = 'rule-preview'; export const AlertReasonPreviewPanel: PreviewPanelPaths = 'alert-reason-preview'; export interface PreviewPanelProps extends FlyoutPanelProps { - key: 'document-details-preview'; + key: typeof DocumentDetailsPreviewPanelKey; path?: PanelPath; params?: { id: string; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/footer.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/footer.tsx index 53309054a3a36..83d93f03ea26b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/footer.tsx @@ -10,6 +10,7 @@ import React, { useCallback } from 'react'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import styled from 'styled-components'; import { euiThemeVars } from '@kbn/ui-theme'; +import { DocumentDetailsIsolateHostPanelKey } from '../shared/constants/panel_keys'; import { FlyoutFooter } from '../../../timelines/components/side_panel/event_details/flyout'; import { useRightPanelContext } from './context'; import { useHostIsolationTools } from '../../../timelines/components/side_panel/event_details/use_host_isolation_tools'; @@ -46,7 +47,7 @@ export const PanelFooter: FC = ({ isPreview }) => { (action: 'isolateHost' | 'unisolateHost' | undefined) => { showHostIsolationPanel(action); openRightPanel({ - id: 'document-details-isolate-host', + id: DocumentDetailsIsolateHostPanelKey, params: { id: eventId, indexName, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/index.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/index.tsx index 23166706c177e..969d481b09407 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/index.tsx @@ -25,7 +25,7 @@ import { useFlyoutIsExpandable } from './hooks/use_flyout_is_expandable'; export type RightPanelPaths = 'overview' | 'table' | 'json'; export interface RightPanelProps extends FlyoutPanelProps { - key: 'document-details-right'; + key: typeof DocumentDetailsRightPanelKey; path?: PanelPath; params?: { id: string; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/constants/panel_keys.ts b/x-pack/plugins/security_solution/public/flyout/document_details/shared/constants/panel_keys.ts index ec2d59791524e..94bf86ca9e078 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/constants/panel_keys.ts +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/constants/panel_keys.ts @@ -5,13 +5,7 @@ * 2.0. */ -import type { IsolateHostPanelProps } from '../../isolate_host'; -import type { LeftPanelProps } from '../../left'; -import type { PreviewPanelProps } from '../../preview'; -import type { RightPanelProps } from '../../right'; - -export const DocumentDetailsRightPanelKey: RightPanelProps['key'] = 'document-details-right'; -export const DocumentDetailsLeftPanelKey: LeftPanelProps['key'] = 'document-details-left'; -export const DocumentDetailsPreviewPanelKey: PreviewPanelProps['key'] = 'document-details-preview'; -export const DocumentDetailsIsolateHostPanelKey: IsolateHostPanelProps['key'] = - 'document-details-isolate-host'; +export const DocumentDetailsRightPanelKey = 'document-details-right' as const; +export const DocumentDetailsLeftPanelKey = 'document-details-left' as const; +export const DocumentDetailsPreviewPanelKey = 'document-details-preview' as const; +export const DocumentDetailsIsolateHostPanelKey = 'document-details-isolate-host' as const; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx index b73dcfe6e0126..1c80297f70182 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.tsx @@ -19,7 +19,11 @@ import { FormattedRelative } from '@kbn/i18n-react'; import React, { useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; - +import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; +import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { useKibana } from '../../../../common/lib/kibana'; +import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; import type { TimelineResultNote } from '../types'; import { getEmptyValue, defaultToEmptyTag } from '../../../../common/components/empty_value'; import { MarkdownRenderer } from '../../../../common/components/markdown_editor'; @@ -32,6 +36,7 @@ import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; import { useSourcererDataView } from '../../../../common/containers/sourcerer'; import { useDeleteNote } from './hooks/use_delete_note'; import { getTimelineNoteSelector } from '../../timeline/tabs/notes/selectors'; +import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '../../../../../common/constants'; export const NotePreviewsContainer = styled.section` padding-top: ${({ theme }) => `${theme.eui.euiSizeS}`}; @@ -51,19 +56,54 @@ const ToggleEventDetailsButtonComponent: React.FC const dispatch = useDispatch(); const { selectedPatterns } = useSourcererDataView(SourcererScopeName.timeline); + const { telemetry } = useKibana().services; + const { openFlyout } = useExpandableFlyoutApi(); + const [isSecurityFlyoutEnabled] = useUiSetting$(ENABLE_EXPANDABLE_FLYOUT_SETTING); + const expandableTimelineFlyoutEnabled = useIsExperimentalFeatureEnabled( + 'expandableTimelineFlyoutEnabled' + ); + const handleClick = useCallback(() => { - dispatch( - timelineActions.toggleDetailPanel({ - panelView: 'eventDetail', - tabType: TimelineTabs.notes, - id: timelineId, - params: { - eventId, - indexName: selectedPatterns.join(','), + const indexName = selectedPatterns.join(','); + + if (isSecurityFlyoutEnabled && expandableTimelineFlyoutEnabled) { + openFlyout({ + right: { + id: DocumentDetailsRightPanelKey, + params: { + id: eventId, + indexName, + scopeId: timelineId, + }, }, - }) - ); - }, [dispatch, eventId, selectedPatterns, timelineId]); + }); + telemetry.reportDetailsFlyoutOpened({ + location: timelineId, + panel: 'right', + }); + } else { + dispatch( + timelineActions.toggleDetailPanel({ + panelView: 'eventDetail', + tabType: TimelineTabs.notes, + id: timelineId, + params: { + eventId, + indexName, + }, + }) + ); + } + }, [ + dispatch, + eventId, + expandableTimelineFlyoutEnabled, + isSecurityFlyoutEnabled, + openFlyout, + selectedPatterns, + telemetry, + timelineId, + ]); return ( ( const urlModifier = (value: string) => { // this is actually only needed for when users click on the Share Alert button and then enable the expandable flyout // (for the old (non-expandable) flyout, we do not need to save anything in the url as we automatically open the flyout here: x-pack/plugins/security_solution/public/detections/pages/alerts/alert_details_redirect.tsx - return `${value}&${URL_PARAM_KEY.flyout}=(preview:!(),right:(id:document-details-right,params:(id:'${eventId}',indexName:${eventIndex},scopeId:${scopeId})))`; + return `${value}&${URL_PARAM_KEY.flyout}=(preview:!(),right:(id:${DocumentDetailsRightPanelKey},params:(id:'${eventId}',indexName:${eventIndex},scopeId:${scopeId})))`; }; const { refetch } = useRefetchByScope({ scopeId }); From 6f805d5867e8b6737096b811c8352c8ce5872db5 Mon Sep 17 00:00:00 2001 From: Bena Kansara <69037875+benakansara@users.noreply.github.com> Date: Mon, 29 Apr 2024 22:28:26 +0200 Subject: [PATCH 014/104] [Alert details page] [Log rate analysis] Adjust time range for long running alerts (#181718) Closes https://github.com/elastic/kibana/issues/181716 Updated `timeRangeEnd` and `deviationMax` for log rate analysis in Custom threshold and Log threshold alerts. ### Current Screenshot 2024-04-25 at 15 49 07 ### After change Screenshot 2024-04-25 at 15 50 32 --- .../components/log_rate_analysis.tsx | 46 ++++++++++++++++-- .../helpers/get_initial_analysis_start.ts | 48 +++++++++++++++++-- .../log_rate_analysis.tsx | 4 +- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/components/log_rate_analysis.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/components/log_rate_analysis.tsx index 84ade2fa5a892..c5e2f2b3648da 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/components/log_rate_analysis.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/components/log_rate_analysis.tsx @@ -108,15 +108,51 @@ export const LogRateAnalysis: FC = ({ r const timeRange = { min: alertStart.clone().subtract(15 * intervalFactor, 'minutes'), - max: alertEnd ? alertEnd.clone().add(1 * intervalFactor, 'minutes') : moment(new Date()), + max: getTimeRangeEnd(), }; - function getDeviationMax() { + function getTimeRangeEnd() { if (alertEnd) { - return alertEnd + if ( + alertStart + .clone() + .add(15 * intervalFactor, 'minutes') + .isAfter(alertEnd) + ) + return alertEnd.clone().add(1 * intervalFactor, 'minutes'); + else { + return alertStart.clone().add(15 * intervalFactor, 'minutes'); + } + } else if ( + alertStart .clone() - .subtract(1 * intervalFactor, 'minutes') - .valueOf(); + .add(15 * intervalFactor, 'minutes') + .isAfter(moment(new Date())) + ) { + return moment(new Date()); + } else { + return alertStart.clone().add(15 * intervalFactor, 'minutes'); + } + } + + function getDeviationMax() { + if (alertEnd) { + if ( + alertStart + .clone() + .add(10 * intervalFactor, 'minutes') + .isAfter(alertEnd) + ) + return alertEnd + .clone() + .subtract(1 * intervalFactor, 'minutes') + .valueOf(); + else { + return alertStart + .clone() + .add(10 * intervalFactor, 'minutes') + .valueOf(); + } } else if ( alertStart .clone() diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/helpers/get_initial_analysis_start.ts b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/helpers/get_initial_analysis_start.ts index 08bc835b7f43e..9b684fd04fdce 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/helpers/get_initial_analysis_start.ts +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/helpers/get_initial_analysis_start.ts @@ -13,16 +13,56 @@ export interface GetInitialAnalysisStartArgs { alertEnd?: Moment; } -export const getDeviationMax = ({ +export const getTimeRangeEnd = ({ alertStart, intervalFactor, alertEnd, }: GetInitialAnalysisStartArgs) => { if (alertEnd) { - return alertEnd + if ( + alertStart + .clone() + .add(15 * intervalFactor, 'minutes') + .isAfter(alertEnd) + ) + return alertEnd.clone().add(1 * intervalFactor, 'minutes'); + else { + return alertStart.clone().add(15 * intervalFactor, 'minutes'); + } + } else if ( + alertStart .clone() - .subtract(1 * intervalFactor, 'minutes') - .valueOf(); + .add(15 * intervalFactor, 'minutes') + .isAfter(moment(new Date())) + ) { + return moment(new Date()); + } else { + return alertStart.clone().add(15 * intervalFactor, 'minutes'); + } +}; + +export const getDeviationMax = ({ + alertStart, + intervalFactor, + alertEnd, +}: GetInitialAnalysisStartArgs) => { + if (alertEnd) { + if ( + alertStart + .clone() + .add(10 * intervalFactor, 'minutes') + .isAfter(alertEnd) + ) + return alertEnd + .clone() + .subtract(1 * intervalFactor, 'minutes') + .valueOf(); + else { + return alertStart + .clone() + .add(10 * intervalFactor, 'minutes') + .valueOf(); + } } else if ( alertStart .clone() diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/log_rate_analysis.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/log_rate_analysis.tsx index b91f393343233..a2ee142e51d09 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/log_rate_analysis.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/log_rate_analysis.tsx @@ -24,7 +24,7 @@ import { CustomThresholdRuleTypeParams } from '../../types'; import { TopAlert } from '../../../..'; import { Color, colorTransformer } from '../../../../../common/custom_threshold_rule/color_palette'; import { getLogRateAnalysisEQQuery } from './helpers/log_rate_analysis_query'; -import { getInitialAnalysisStart } from './helpers/get_initial_analysis_start'; +import { getInitialAnalysisStart, getTimeRangeEnd } from './helpers/get_initial_analysis_start'; export interface AlertDetailsLogRateAnalysisProps { alert: TopAlert>; @@ -80,7 +80,7 @@ export function LogRateAnalysis({ const timeRange = { min: alertStart.clone().subtract(15 * intervalFactor, 'minutes'), - max: alertEnd ? alertEnd.clone().add(1 * intervalFactor, 'minutes') : moment(new Date()), + max: getTimeRangeEnd({ alertStart, intervalFactor, alertEnd }), }; const logRateAnalysisTitle = i18n.translate( From a47888a62213cfa9af4725e7435d1906fa597184 Mon Sep 17 00:00:00 2001 From: Candace Park <56409205+parkiino@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:35:05 -0400 Subject: [PATCH 015/104] [Security Solution][Defend Workflows][Event Filters] Fixes bug where wrong callout is shown after switching operators (#181791) ## Summary - [x] Fixes bug where a stale warning callout is shown in create/edit event filters even when the operator is changed to fix the warning # Screenshots BEFORE ![image](https://github.com/elastic/kibana/assets/56409205/6d918d84-fbe5-4f5a-893c-1a7146d71a2d) AFTER ![stalecallout](https://github.com/elastic/kibana/assets/56409205/6d71c5da-e60a-49a3-8d01-6092cf021ab8) --- .../management/pages/event_filters/view/components/form.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx index 6c231c0931edd..d9db594c4e73c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx @@ -420,6 +420,7 @@ export const EventFiltersForm: React.FC { if ( validateHasWildcardWithWrongOperator({ From 957ff083c4e0c738d8d0b2ae81ae468c3a1abb7b Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 29 Apr 2024 14:52:24 -0600 Subject: [PATCH 016/104] [data visualizer] fix clicking field statistics 'Explore in maps' button does not take users to maps (#181903) Fixes https://github.com/elastic/kibana/issues/181900 PR resolves issue by 1. strongly typing `triggerOptions` to `VisualizeFieldContext` so future type changes to `VisualizeFieldContext` will be picked up by this file 2. Add more protection to `visualizeGeoFieldAction.isCompatible` method to prevent executing invalid context. Out of scope for PR - updating "field statistics" to not show "Explore in maps" when action compatibility check fails. `visualizeGeoFieldAction.isCompatible` is async while `getActions` is sync. ### test 1. install sample web logs 4. Open discover 5. Change data table view to field statistics by clicking "Field statistics" toggle. 6. Click "Explore in maps" action button for field `geo.coordinates`. 7. Verify map is opened showing geo.coordinates --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/components/field_data_row/action_menu/actions.ts | 5 +++-- .../public/trigger_actions/visualize_geo_field_action.ts | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) 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 eebbfe3826a68..74d16b6814bd7 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,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import type { Action } from '@elastic/eui/src/components/basic_table/action_types'; import type { MutableRefObject } from 'react'; import type { DataView } from '@kbn/data-views-plugin/public'; +import type { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import { VISUALIZE_GEO_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public'; import type { Refresh } from '@kbn/ml-date-picker'; import { mlTimefilterRefresh$ } from '@kbn/ml-date-picker'; @@ -85,8 +86,8 @@ export function getActions( }, onClick: async (item: FieldVisConfig) => { if (services?.uiActions && dataView) { - const triggerOptions = { - indexPatternId: dataView.id, + const triggerOptions: VisualizeFieldContext = { + dataViewSpec: dataView.toSpec(), fieldName: item.fieldName, contextualFields: [], originatingApp: APP_ID, diff --git a/x-pack/plugins/maps/public/trigger_actions/visualize_geo_field_action.ts b/x-pack/plugins/maps/public/trigger_actions/visualize_geo_field_action.ts index 417ff0d0bf1fe..fa63827844ed1 100644 --- a/x-pack/plugins/maps/public/trigger_actions/visualize_geo_field_action.ts +++ b/x-pack/plugins/maps/public/trigger_actions/visualize_geo_field_action.ts @@ -24,7 +24,9 @@ export const visualizeGeoFieldAction = createAction({ i18n.translate('xpack.maps.discover.visualizeFieldLabel', { defaultMessage: 'Visualize in Maps', }), - isCompatible: async () => !!getVisualizeCapabilities().show, + isCompatible: async (context) => { + return Boolean(!!getVisualizeCapabilities().show && context.dataViewSpec && context.fieldName); + }, getHref: async (context) => { const { getMapsLink } = await import('./get_maps_link'); const { app, path } = await getMapsLink(context); From 4a90df23b6ddda3e230059ab70e04a0a2e905ad6 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 00:08:52 +0200 Subject: [PATCH 017/104] [Fix] fix type issues from unparameterized PropsWithChildren type usages (#182014) ## Summary Original problem: `PropsWithChildren` require a generic type parameter (there's no default). This was not made visible in the merged PR, because we had type-checking on the PRs temporarily (accidentally) removed. Thsi PR fixes the fallout from https://github.com/elastic/kibana/pull/181257 => Errors: https://buildkite.com/elastic/kibana-on-merge/builds/44454 --- .buildkite/pipelines/pull_request/base.yml | 10 ++++++++++ .../src/i18n_context_mock.tsx | 2 +- .../src/maintenance_window_callout/index.test.tsx | 4 ++-- .../src/context/cell_actions_context.test.tsx | 2 +- packages/kbn-i18n-react/src/provider.tsx | 2 +- .../mocks/src/storybook_template.tsx | 2 +- .../error_boundary/src/ui/error_boundary.test.tsx | 2 +- .../content_client_mutation_hooks.test.tsx | 2 +- .../content_client_query_hooks.test.tsx | 2 +- src/plugins/custom_integrations/public/mocks.tsx | 2 +- src/plugins/custom_integrations/public/plugin.tsx | 2 +- src/plugins/custom_integrations/public/types.ts | 2 +- .../dashboard_listing/dashboard_listing.test.tsx | 8 +++++--- .../flyout_panels/flyout_panels_content.tsx | 2 +- .../application/context/context_app_content.tsx | 2 +- .../global_flyout/global_flyout.tsx | 2 +- .../components/page_loading/page_loading.tsx | 2 +- .../components/__stories__/form_global_fields.tsx | 4 ++-- .../interactive_setup/public/text_truncate.tsx | 2 +- .../interactive_setup/public/use_verification.tsx | 2 +- .../public/services/create/provider.tsx | 2 +- .../public/services/create/registry.tsx | 2 +- src/plugins/presentation_util/public/types.ts | 2 +- .../save_modal/show_saved_object_save_modal.tsx | 2 +- .../public/management_section/mount_section.tsx | 2 +- .../drilldown_manager_footer.tsx | 2 +- src/plugins/usage_collection/public/plugin.tsx | 2 +- .../src/components/date_picker_wrapper.test.tsx | 4 ++-- x-pack/packages/ml/url_state/src/url_state.tsx | 2 +- .../data_quality_context/index.test.tsx | 2 +- .../impl/data_quality/use_mappings/index.test.tsx | 2 +- .../impl/data_quality/use_stats/index.test.tsx | 4 ++-- .../use_unallowed_values/index.test.tsx | 2 +- .../navigation/src/__mocks__/context.tsx | 2 +- .../change_point_detection_context.tsx | 6 ++++-- .../log_categorization/format_category.tsx | 2 +- .../aiops/public/shared_lazy_components.tsx | 2 +- x-pack/plugins/alerting/public/lib/test_utils.tsx | 4 ++-- .../components/submit_button.test.tsx | 2 +- .../home/my_workpads/upload_dropzone.tsx | 2 +- .../workpad/hooks/use_autoplay_helper.test.tsx | 2 +- .../workpad/hooks/use_refresh_helper.test.tsx | 2 +- .../routes/workpad/workpad_presentation_helper.tsx | 2 +- .../canvas/public/routes/workpad/workpad_route.tsx | 4 ++-- .../routes/workpad/workpad_routing_context.tsx | 2 +- .../use_cases_add_to_existing_case_modal.test.tsx | 2 +- .../public/components/create/assignees.test.tsx | 2 +- .../public/components/create/category.test.tsx | 2 +- .../public/components/create/connector.test.tsx | 2 +- .../use_cases_add_to_new_case_flyout.test.tsx | 2 +- .../components/create/sync_alerts_toggle.test.tsx | 2 +- .../cases/public/components/create/tags.test.tsx | 2 +- .../cases/public/components/create/title.test.tsx | 2 +- .../user_actions/use_user_actions_handler.test.tsx | 4 +++- .../actions/__mocks__/action_wrapper.tsx | 2 +- .../actions/add_to_existing_case.test.tsx | 2 +- .../cases/public/containers/use_get_case.test.tsx | 2 +- .../containers/use_get_case_metrics.test.tsx | 4 +++- .../cases/public/mocks/mock_cases_context.tsx | 2 +- x-pack/plugins/cloud/public/mocks.tsx | 2 +- x-pack/plugins/cloud/public/plugin.tsx | 4 ++-- x-pack/plugins/cloud/public/types.ts | 2 +- .../cloud_chat/.storybook/decorator.tsx | 2 +- .../public/components/chat/when_idle.tsx | 2 +- .../cloud_chat/public/plugin.tsx | 2 +- .../additional_controls.tsx | 2 +- .../public/pages/rules/rules_container.test.tsx | 4 +++- .../auto_follow_pattern_delete_provider.d.ts | 2 +- .../file_data_visualizer/file_data_visualizer.tsx | 2 +- .../public/lazy_load_bundle/component_wrapper.tsx | 2 +- .../components/api_logs/api_log/api_log_flyout.tsx | 2 +- .../empty_search_applications_prompt.tsx | 2 +- .../connector/sync_rules/connector_sync_form.tsx | 2 +- .../pipelines/ml_inference/inference_config.tsx | 2 +- .../public/applications/index.tsx | 2 +- .../shared/flash_messages/flash_messages.tsx | 2 +- .../shared/layout/endpoints_header_action.tsx | 2 +- .../field_stats_flyout_provider.tsx | 2 +- .../components/page_header/page_header.tsx | 2 +- .../advanced_detector_modal/descriptions.tsx | 14 +++++++------- .../categorization_partition_field/description.tsx | 6 +----- .../categorization_view/field_examples.tsx | 2 +- .../components/geo_field/description.tsx | 2 +- .../components/influencers/description.tsx | 2 +- .../components/population_field/description.tsx | 2 +- .../components/rare_field/description.tsx | 2 +- .../components/sparse_data/description.tsx | 2 +- .../components/split_field/description.tsx | 2 +- .../components/summary_step/components/common.tsx | 2 +- .../components/notifications_list.test.tsx | 2 +- .../timeseriesexplorer/timeseriesexplorer.test.tsx | 2 +- .../chart_preview/chart_preview_helper.tsx | 2 +- .../apm/public/hooks/use_breakpoints.test.tsx | 2 +- .../criterion_preview_chart.tsx | 4 ++-- .../components/expression_editor/editor.tsx | 2 +- .../public/components/loading_overlay_wrapper.tsx | 2 +- .../logs/log_entry_categories/page_providers.tsx | 2 +- .../pages/logs/log_entry_rate/page_providers.tsx | 2 +- .../infra/public/pages/logs/page_providers.tsx | 2 +- .../public/pages/logs/stream/page_providers.tsx | 2 +- .../metric_detail/hooks/metrics_time.test.tsx | 2 +- .../hooks/use_metrics_explorer_data.test.tsx | 2 +- .../log_entry_actions_menu.test.tsx | 2 +- .../logging/log_text_stream/log_text_separator.tsx | 2 +- .../public/hooks/use_conversation.test.tsx | 2 +- .../common/wrappers/service_allowed_wrapper.tsx | 2 +- .../monitor_details/monitor_pending_wrapper.tsx | 2 +- .../contexts/synthetics_refresh_context.tsx | 2 +- .../components/common/monitor_tags.test.tsx | 2 +- .../contexts/uptime_refresh_context.tsx | 2 +- .../hooks/use_overview_filter_check.test.tsx | 2 +- .../osquery_results/test_utils.tsx | 4 +++- .../public/lib/ilm_policy_status_context.tsx | 2 +- .../public/components/title_panel.tsx | 2 +- .../sources_panel_for_sidebar.test.tsx | 2 +- .../sources_panel_for_start_chat.test.tsx | 2 +- .../user_profile/user_profile.test.tsx | 5 +++-- .../security/public/components/breadcrumb.tsx | 4 ++-- .../public/assistant/provider.tsx | 2 +- .../public/assistant/send_to_timeline/index.tsx | 1 + .../public/common/__mocks__/query_wrapper.tsx | 2 +- .../common/components/current_license/index.tsx | 2 +- .../common/components/endpoint/route_capture.tsx | 2 +- .../cti_details/threat_summary_view.tsx | 2 +- .../events_viewer/event_details_width_context.tsx | 2 +- .../onboarding/__mocks__/product_switch.tsx | 2 +- .../onboarding/__mocks__/toggle_panel.tsx | 2 +- .../ml/permissions/ml_capabilities_provider.tsx | 2 +- .../security_route_page_wrapper/index.tsx | 1 + .../public/common/hooks/use_upselling.test.tsx | 2 +- .../public/common/mock/storybook_providers.tsx | 2 +- .../dashboards/context/dashboard_context.tsx | 2 +- .../rule_details/json_diff/diff_view.tsx | 2 +- .../rule_details/json_diff/json_diff.test.tsx | 2 +- .../rule_details/rule_details_flyout.tsx | 2 +- .../bulk_action_rule_errors_list.test.tsx | 2 +- .../use_execution_events.test.tsx | 2 +- .../use_execution_results.test.tsx | 2 +- .../use_host_isolation_action.test.tsx | 2 +- .../use_installed_integrations.test.tsx | 2 +- .../rule_status_failed_callout.test.tsx | 2 +- .../right/hooks/use_process_data.test.tsx | 2 +- .../components/exception_items_summary.test.tsx | 2 +- .../endpoint_agent_tamper_protection_extension.tsx | 14 ++++++++------ .../view/ingest_manager_integration/mocks.tsx | 2 +- .../policy_settings_form/policy_settings_form.tsx | 3 ++- .../public/overview/pages/landing.test.tsx | 2 +- .../timeline/body/events/stateful_event.tsx | 11 +++++++---- .../tabs/session/use_session_view.test.tsx | 2 +- .../timeline/unified_components/index.test.tsx | 2 +- .../public/common/services/__mocks__/index.tsx | 2 +- .../components/index_management/overview_panel.tsx | 4 ++-- .../public/application/components/overview.tsx | 2 +- .../serverless_search/public/test/test_utils.tsx | 2 +- .../spaces/public/spaces_context/context.tsx | 5 +++-- .../plugins/spaces/public/spaces_context/types.ts | 2 +- .../components/source_fields_select.test.tsx | 2 +- .../expression/esql_query_expression.test.tsx | 2 +- .../test_query_row/test_query_row_table.test.tsx | 2 +- .../public/containers/enterprise_guard.tsx | 2 +- .../public/containers/field_types_provider.tsx | 2 +- .../public/containers/filters_global.tsx | 2 +- .../public/containers/inspector.tsx | 2 +- .../public/containers/integrations_guard.tsx | 2 +- .../containers/security_solution_page_wrapper.tsx | 2 +- .../public/mocks/test_providers.tsx | 2 +- .../indicators/containers/block_list_provider.tsx | 2 +- .../modules/indicators/containers/filters.tsx | 2 +- .../public/modules/indicators/pages/indicators.tsx | 2 +- .../public/app/hooks/use_index_data.test.tsx | 2 +- .../edit_transform_flyout_state.test.tsx | 2 +- .../components/transform_list/use_actions.test.tsx | 2 +- .../components/transform_list/use_columns.test.tsx | 2 +- .../toast_with_circuit_breaker_content.tsx | 2 +- .../public/application/sections/test_utils.tsx | 4 ++-- .../components/loading_issues_error.tsx | 2 +- 176 files changed, 235 insertions(+), 207 deletions(-) diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml index 5a4d7afcaa128..e36e3ab5f59dd 100644 --- a/.buildkite/pipelines/pull_request/base.yml +++ b/.buildkite/pipelines/pull_request/base.yml @@ -70,6 +70,16 @@ steps: - exit_status: '-1' limit: 3 + - command: .buildkite/scripts/steps/check_types.sh + label: 'Check Types' + agents: + queue: n2-4-spot + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - command: .buildkite/scripts/steps/lint_with_types.sh label: 'Linting (with types)' agents: diff --git a/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx b/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx index 2d657a4afcfb9..33a515f7a1a5d 100644 --- a/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx +++ b/packages/core/i18n/core-i18n-browser-mocks/src/i18n_context_mock.tsx @@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n'; const emptyMessages = {}; -export const I18nProviderMock: FC = ({ children }) => { +export const I18nProviderMock: FC> = ({ children }) => { return ( ({ fetchActiveMaintenanceWindows: jest.fn(() => Promise.resolve([])), })); -const TestProviders: FC = ({ children }) => { +const TestProviders: FC> = ({ children }) => { const queryClient = new QueryClient(); return ( @@ -231,7 +231,7 @@ describe('MaintenanceWindowCallout', () => { warn: console.warn, }, }); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); return wrapper; diff --git a/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx b/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx index 2184fc0fa7967..2cec616176372 100644 --- a/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx +++ b/packages/kbn-cell-actions/src/context/cell_actions_context.test.tsx @@ -13,7 +13,7 @@ import { CellActionsProvider, useCellActionsContext } from './cell_actions_conte const action = makeAction('action-1', 'icon', 1); const mockGetTriggerCompatibleActions = jest.fn(async () => [action]); -const ContextWrapper: FC = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( {children} diff --git a/packages/kbn-i18n-react/src/provider.tsx b/packages/kbn-i18n-react/src/provider.tsx index cc3a5c475ce6f..f31cc6dfb250c 100644 --- a/packages/kbn-i18n-react/src/provider.tsx +++ b/packages/kbn-i18n-react/src/provider.tsx @@ -20,7 +20,7 @@ import { PseudoLocaleWrapper } from './pseudo_locale_wrapper'; * IntlProvider should wrap react app's root component (inside each react render method). */ -export const I18nProvider: FC = ({ children }) => ( +export const I18nProvider: FC> = ({ children }) => ( = ({ children }) => { +export const Template: FC> = ({ children }) => { return ( <> diff --git a/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx b/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx index bc3fa49741ac8..472aeba92ad5a 100644 --- a/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx +++ b/packages/shared-ux/error_boundary/src/ui/error_boundary.test.tsx @@ -22,7 +22,7 @@ describe('', () => { services = getServicesMock(); }); - const Template: FC = ({ children }) => { + const Template: FC> = ({ children }) => { return ( {children} diff --git a/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx b/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx index b16e5dc5be72e..fc44b8fa774f4 100644 --- a/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx +++ b/src/plugins/content_management/public/content_client/content_client_mutation_hooks.test.tsx @@ -28,7 +28,7 @@ const setup = () => { }); const contentClient = new ContentClient(() => crudClient, contentTypeRegistry); - const Wrapper: FC = ({ children }) => ( + const Wrapper: FC> = ({ children }) => ( {children} ); diff --git a/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx b/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx index 536dbf0aa6fd2..6811ef63afe58 100644 --- a/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx +++ b/src/plugins/content_management/public/content_client/content_client_query_hooks.test.tsx @@ -24,7 +24,7 @@ const setup = () => { }); const contentClient = new ContentClient(() => crudClient, contentTypeRegistry); - const Wrapper: FC = ({ children }) => ( + const Wrapper: FC> = ({ children }) => ( {children} ); diff --git a/src/plugins/custom_integrations/public/mocks.tsx b/src/plugins/custom_integrations/public/mocks.tsx index d21eb1bbc3e8b..837a22b45626c 100644 --- a/src/plugins/custom_integrations/public/mocks.tsx +++ b/src/plugins/custom_integrations/public/mocks.tsx @@ -25,7 +25,7 @@ function createCustomIntegrationsStart(): jest.Mocked { return { languageClientsUiComponents: {}, - ContextProvider: jest.fn(({ children }: PropsWithChildren) => ( + ContextProvider: jest.fn(({ children }: PropsWithChildren) => ( {children} diff --git a/src/plugins/custom_integrations/public/plugin.tsx b/src/plugins/custom_integrations/public/plugin.tsx index c1de44473aa7b..75b2edbff5435 100755 --- a/src/plugins/custom_integrations/public/plugin.tsx +++ b/src/plugins/custom_integrations/public/plugin.tsx @@ -71,7 +71,7 @@ export class CustomIntegrationsPlugin })), }; - const ContextProvider: FC = ({ children }) => ( + const ContextProvider: FC> = ({ children }) => ( {children} diff --git a/src/plugins/custom_integrations/public/types.ts b/src/plugins/custom_integrations/public/types.ts index cd1f150ccaddb..c3991ec076907 100755 --- a/src/plugins/custom_integrations/public/types.ts +++ b/src/plugins/custom_integrations/public/types.ts @@ -15,7 +15,7 @@ export interface CustomIntegrationsSetup { } export interface CustomIntegrationsStart { - ContextProvider: FC; + ContextProvider: FC>; languageClientsUiComponents: Record; } diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx index 64d29f04a42ae..70893d2b2d890 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx @@ -27,9 +27,11 @@ jest.mock('@kbn/content-management-table-list-view-table', () => { return { __esModule: true, ...originalModule, - TableListViewKibanaProvider: jest.fn().mockImplementation(({ children }: PropsWithChildren) => { - return <>{children}; - }), + TableListViewKibanaProvider: jest + .fn() + .mockImplementation(({ children }: PropsWithChildren) => { + return <>{children}; + }), }; }); jest.mock('@kbn/content-management-table-list-view', () => { diff --git a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx index ff36dcc45b063..64c8362e644af 100644 --- a/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx +++ b/src/plugins/data_view_editor/public/components/flyout_panels/flyout_panels_content.tsx @@ -9,7 +9,7 @@ import React, { useEffect, FC, PropsWithChildren } from 'react'; import { useFlyoutPanelContext } from './flyout_panel'; -export const PanelContent: FC = (props) => { +export const PanelContent: FC> = (props) => { const { registerContent } = useFlyoutPanelContext(); useEffect(() => { diff --git a/src/plugins/discover/public/application/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx index 875b4241d314d..6c82a9408d003 100644 --- a/src/plugins/discover/public/application/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -242,7 +242,7 @@ export function ContextAppContent({ ); } -const WrapperWithPadding: FC = ({ children }) => { +const WrapperWithPadding: FC> = ({ children }) => { const padding = useEuiPaddingSize('s'); return ( diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx b/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx index 28495774d2c3b..ca5f8de20c3f0 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/global_flyout/global_flyout.tsx @@ -41,7 +41,7 @@ const DEFAULT_FLYOUT_PROPS = { maxWidth: 500, }; -export const GlobalFlyoutProvider: FC = ({ children }) => { +export const GlobalFlyoutProvider: FC> = ({ children }) => { const [showFlyout, setShowFlyout] = useState(false); const [activeContent, setActiveContent] = useState | undefined>(undefined); diff --git a/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx index c3f1ef25545d8..11c7b96e56c02 100644 --- a/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx +++ b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx @@ -9,7 +9,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { EuiLoadingSpinner, EuiText, EuiPageTemplate } from '@elastic/eui'; -export const PageLoading: FC = ({ children }) => { +export const PageLoading: FC> = ({ children }) => { return ( } diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx index a6faefdf9a22f..ba9c25f43d924 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/form_global_fields.tsx @@ -48,7 +48,7 @@ const useGlobalFields = () => { return ctx; }; -const FormGlobalFields: FC = ({ children }) => { +const FormGlobalFields: FC> = ({ children }) => { return ( {(fields) => { @@ -170,7 +170,7 @@ const useGlobalFields = () => { return ctx; }; -const FormGlobalFields: FC = ({ children }) => { +const FormGlobalFields: FC> = ({ children }) => { return ( {(fields) => { diff --git a/src/plugins/interactive_setup/public/text_truncate.tsx b/src/plugins/interactive_setup/public/text_truncate.tsx index 16fb12d5cb4c5..d4ba873805a3d 100644 --- a/src/plugins/interactive_setup/public/text_truncate.tsx +++ b/src/plugins/interactive_setup/public/text_truncate.tsx @@ -10,7 +10,7 @@ import { EuiToolTip } from '@elastic/eui'; import type { FC, PropsWithChildren } from 'react'; import React, { useLayoutEffect, useRef, useState } from 'react'; -export const TextTruncate: FC = ({ children }) => { +export const TextTruncate: FC> = ({ children }) => { const textRef = useRef(null); const [showTooltip, setShowTooltip] = useState(false); diff --git a/src/plugins/interactive_setup/public/use_verification.tsx b/src/plugins/interactive_setup/public/use_verification.tsx index febac9ddf73ef..79bcbedc4af51 100644 --- a/src/plugins/interactive_setup/public/use_verification.tsx +++ b/src/plugins/interactive_setup/public/use_verification.tsx @@ -38,7 +38,7 @@ const [OuterVerificationProvider, useVerification] = constate( } ); -const InnerVerificationProvider: FC = ({ children }) => { +const InnerVerificationProvider: FC> = ({ children }) => { const { http } = useKibana(); const { status, setStatus, setCode } = useVerification(); diff --git a/src/plugins/presentation_util/public/services/create/provider.tsx b/src/plugins/presentation_util/public/services/create/provider.tsx index 4844087298003..d6e4e19bfded2 100644 --- a/src/plugins/presentation_util/public/services/create/provider.tsx +++ b/src/plugins/presentation_util/public/services/create/provider.tsx @@ -62,7 +62,7 @@ export class PluginServiceProvider< private _requiredServices?: RequiredServices; private context = createContext(null); private pluginService: Service | null = null; - public readonly Provider: FC = ({ children }) => { + public readonly Provider: FC> = ({ children }) => { return {children}; }; diff --git a/src/plugins/presentation_util/public/services/create/registry.tsx b/src/plugins/presentation_util/public/services/create/registry.tsx index 8b0b2d4d194d7..6b40bb5027c29 100644 --- a/src/plugins/presentation_util/public/services/create/registry.tsx +++ b/src/plugins/presentation_util/public/services/create/registry.tsx @@ -58,7 +58,7 @@ export class PluginServiceRegistry< // Collect and combine Context.Provider elements from each Service Provider into a single // Functional Component. - const provider: FC = ({ children }) => ( + const provider: FC> = ({ children }) => ( <> {values.reduceRight((acc, serviceProvider) => { return {acc}; diff --git a/src/plugins/presentation_util/public/types.ts b/src/plugins/presentation_util/public/types.ts index 0476c0dca1fe4..85a22f8c1d13e 100644 --- a/src/plugins/presentation_util/public/types.ts +++ b/src/plugins/presentation_util/public/types.ts @@ -17,7 +17,7 @@ import { PresentationLabsService } from './services/labs/types'; export interface PresentationUtilPluginSetup {} export interface PresentationUtilPluginStart { - ContextProvider: FC; + ContextProvider: FC>; labsService: PresentationLabsService; registerExpressionsLanguage: typeof registerExpressionsLanguage; } diff --git a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx index b930f51f37bb3..5d04e5b10ed85 100644 --- a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx @@ -32,7 +32,7 @@ interface MinimalSaveModalProps { export function showSaveModal( saveModal: React.ReactElement, - Wrapper?: FC + Wrapper?: FC> ) { const container = document.createElement('div'); const closeModal = () => { diff --git a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx index 72632f078620f..57103921c909a 100644 --- a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx +++ b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx @@ -43,7 +43,7 @@ export const mountManagementSection = async ({ core, mountParams }: MountParams) coreStart.chrome.docTitle.change(title); - const RedirectToHomeIfUnauthorized: FC = ({ children }) => { + const RedirectToHomeIfUnauthorized: FC> = ({ children }) => { const allowed = capabilities?.management?.kibana?.objects ?? false; if (!allowed) { diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx index ce22bffe748c6..c82535303f05b 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/containers/drilldown_manager_footer/drilldown_manager_footer.tsx @@ -9,7 +9,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { useDrilldownManager } from '../context'; -export const DrilldownManagerFooter: FC = ({ children }) => { +export const DrilldownManagerFooter: FC> = ({ children }) => { const drilldowns = useDrilldownManager(); React.useEffect(() => { drilldowns.setFooter(children); diff --git a/src/plugins/usage_collection/public/plugin.tsx b/src/plugins/usage_collection/public/plugin.tsx index 3bd66b7370620..208a58df9de22 100644 --- a/src/plugins/usage_collection/public/plugin.tsx +++ b/src/plugins/usage_collection/public/plugin.tsx @@ -74,7 +74,7 @@ export interface UsageCollectionSetup { * } * ``` */ - ApplicationUsageTrackingProvider: FC; + ApplicationUsageTrackingProvider: FC>; }; /** Report whenever a UI event occurs for UI counters to report it **/ diff --git a/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx b/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx index 035e89991d0f3..57f158b22c4d4 100644 --- a/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx +++ b/x-pack/packages/ml/date_picker/src/components/date_picker_wrapper.test.tsx @@ -27,10 +27,10 @@ jest.mock('@elastic/eui', () => { const EuiSuperDatePickerMock = jest.fn(() => { return null; }); - const EuiFlexGroupMock = jest.fn(({ children }: PropsWithChildren) => { + const EuiFlexGroupMock = jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }); - const EuiFlexItemMock = jest.fn(({ children }: PropsWithChildren) => { + const EuiFlexItemMock = jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }); return { diff --git a/x-pack/packages/ml/url_state/src/url_state.tsx b/x-pack/packages/ml/url_state/src/url_state.tsx index 670da0cb42724..1aa796187f9d4 100644 --- a/x-pack/packages/ml/url_state/src/url_state.tsx +++ b/x-pack/packages/ml/url_state/src/url_state.tsx @@ -92,7 +92,7 @@ export const urlStateStore = createContext({ export const { Provider } = urlStateStore; -export const UrlStateProvider: FC = ({ children }) => { +export const UrlStateProvider: FC> = ({ children }) => { const history = useHistory(); const { search: searchString } = useLocation(); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx index 59e0c83cebd94..43cc7ec6051c6 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/data_quality_context/index.test.tsx @@ -19,7 +19,7 @@ const mockTelemetryEvents = { reportDataQualityIndexChecked: mockReportDataQualityIndexChecked, reportDataQualityCheckAllCompleted: mockReportDataQualityCheckAllClicked, }; -const ContextWrapper: FC = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( = ({ children }) => ( ); -const ContextWrapperILMNotAvailable: FC = ({ children }) => ( +const ContextWrapperILMNotAvailable: FC> = ({ children }) => ( = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( (mockCoreStart); -export const NavigationProvider: FC = ({ children }) => ( +export const NavigationProvider: FC> = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx index bf977c4f2a399..2a9ab8d535fa1 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx @@ -99,7 +99,7 @@ export const useChangePointDetectionControlsContext = () => { return useContext(ChangePointDetectionControlsContext); }; -export const ChangePointDetectionControlsContextProvider: FC = ({ +export const ChangePointDetectionControlsContextProvider: FC> = ({ children, }) => { const { dataView } = useDataSource(); @@ -129,7 +129,9 @@ export const ChangePointDetectionControlsContextProvider: FC ); }; -export const ChangePointDetectionContextProvider: FC = ({ children }) => { +export const ChangePointDetectionContextProvider: FC> = ({ + children, +}) => { const { dataView, savedSearch } = useDataSource(); const { uiSettings, diff --git a/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx index 04bac15bc9bdc..7cca9f9e8cada 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx @@ -175,7 +175,7 @@ export const FormattedTokens: FC = ({ category }) => { ); }; -const WrapInText: FC = ({ children }) => ( +const WrapInText: FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/aiops/public/shared_lazy_components.tsx b/x-pack/plugins/aiops/public/shared_lazy_components.tsx index d25ba022a1f29..fe9e31f146590 100644 --- a/x-pack/plugins/aiops/public/shared_lazy_components.tsx +++ b/x-pack/plugins/aiops/public/shared_lazy_components.tsx @@ -20,7 +20,7 @@ const LogRateAnalysisContentWrapperLazy = React.lazy( () => import('./components/log_rate_analysis/log_rate_analysis_content') ); -const LazyWrapper: FC = ({ children }) => ( +const LazyWrapper: FC> = ({ children }) => ( }>{children} diff --git a/x-pack/plugins/alerting/public/lib/test_utils.tsx b/x-pack/plugins/alerting/public/lib/test_utils.tsx index c05d8650832b4..3693e2ea6ccb0 100644 --- a/x-pack/plugins/alerting/public/lib/test_utils.tsx +++ b/x-pack/plugins/alerting/public/lib/test_utils.tsx @@ -29,7 +29,7 @@ export interface AppMockRenderer { render: UiRender; coreStart: CoreStart; queryClient: QueryClient; - AppWrapper: FC; + AppWrapper: FC>; mocked: { setBadge: jest.Mock; }; @@ -78,7 +78,7 @@ export const createAppMockRenderer = ({ setBadge: mockedSetBadge, }, }; - const AppWrapper = React.memo(({ children }) => ( + const AppWrapper = React.memo>(({ children }) => ( {children} diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx index 5e6fe915fcc08..0821200e98475 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/submit_button.test.tsx @@ -17,7 +17,7 @@ import { AppMockRenderer, createAppMockRenderer } from '../../../lib/test_utils' describe('SubmitButton', () => { const onSubmit = jest.fn(); - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm({ defaultValue: { title: 'title' }, schema: { diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx index 7d9284a4fcca2..10ba1c3e06b70 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx @@ -15,7 +15,7 @@ import { UploadDropzone as Component } from './upload_dropzone.component'; const { WorkpadDropzone: errors } = ErrorStrings; -export const UploadDropzone: FC = ({ children }) => { +export const UploadDropzone: FC> = ({ children }) => { const notify = useNotifyService(); const uploadWorkpad = useImportWorkpad(); const [isDisabled, setIsDisabled] = useState(false); diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx index b9de9013bc015..d293d8deade41 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx @@ -19,7 +19,7 @@ const getMockedContext = (context: any) => ...context, } as WorkpadRoutingContextType); -const getContextWrapper: (context: WorkpadRoutingContextType) => FC = +const getContextWrapper: (context: WorkpadRoutingContextType) => FC> = (context) => ({ children }) => {children}; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx index 0453444f0185e..e2b365691c1c0 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx @@ -31,7 +31,7 @@ const getMockedContext = (context: any) => const getContextWrapper = (context: WorkpadRoutingContextType) => - ({ children }: PropsWithChildren) => + ({ children }: PropsWithChildren) => {children}; describe('useRefreshHelper', () => { diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx index 067359aa00e89..0dfb4dd8fbf78 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx @@ -21,7 +21,7 @@ const getWorkpadLabel = () => defaultMessage: 'Workpad', }); -export const WorkpadPresentationHelper: FC = ({ children }) => { +export const WorkpadPresentationHelper: FC> = ({ children }) => { const platformService = usePlatformService(); const workpad = useSelector(getWorkpad); useFullscreenPresentationHelper(); diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx index 0afcae8dc40e6..733a0b2d2b9af 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx @@ -110,7 +110,7 @@ const ExportWorkpadRouteComponent: FC<{ route: WorkpadRouteProps }> = ({ route: ); }; -export const ExportRouteManager: FC = ({ children }) => { +export const ExportRouteManager: FC> = ({ children }) => { const params = useParams(); usePageSync(); @@ -123,7 +123,7 @@ export const ExportRouteManager: FC = ({ children }) => { return <>{children}; }; -export const WorkpadHistoryManager: FC = ({ children }) => { +export const WorkpadHistoryManager: FC> = ({ children }) => { useRestoreHistory(); useWorkpadHistory(); usePageSync(); diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx index 39a2f94e175ab..572446548af0e 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_routing_context.tsx @@ -46,7 +46,7 @@ export const WorkpadRoutingContext = createContext( basicWorkpadRoutingContext ); -export const WorkpadRoutingContextComponent: FC = ({ children }) => { +export const WorkpadRoutingContextComponent: FC> = ({ children }) => { const routingContext = useRoutingContext(); return ( diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx index 59b4f012147ee..05eeb2b000a3f 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/use_cases_add_to_existing_case_modal.test.tsx @@ -65,7 +65,7 @@ describe('use cases add to existing case modal hook', () => { const dispatch = jest.fn(); let appMockRender: AppMockRenderer; - const wrapper: FC = ({ children }) => { + const wrapper: FC> = ({ children }) => { return ( { let globalForm: FormHook; let appMockRender: AppMockRenderer; - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm(); globalForm = form; diff --git a/x-pack/plugins/cases/public/components/create/category.test.tsx b/x-pack/plugins/cases/public/components/create/category.test.tsx index 85d5072bccc58..72428bbd1ff34 100644 --- a/x-pack/plugins/cases/public/components/create/category.test.tsx +++ b/x-pack/plugins/cases/public/components/create/category.test.tsx @@ -27,7 +27,7 @@ describe('Category', () => { let appMockRender: AppMockRenderer; const onSubmit = jest.fn(); - const FormComponent: FC = ({ children }) => { + const FormComponent: FC> = ({ children }) => { const { form } = useForm({ onSubmit }); return ( diff --git a/x-pack/plugins/cases/public/components/create/connector.test.tsx b/x-pack/plugins/cases/public/components/create/connector.test.tsx index d77983c662524..1cf7c82075136 100644 --- a/x-pack/plugins/cases/public/components/create/connector.test.tsx +++ b/x-pack/plugins/cases/public/components/create/connector.test.tsx @@ -66,7 +66,7 @@ describe('Connector', () => { let appMockRender: AppMockRenderer; let globalForm: FormHook; - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm({ defaultValue: { connectorId: connectorsMock[0].id, fields: null }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx b/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx index e43a958430e1b..a7aa207162989 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/use_cases_add_to_new_case_flyout.test.tsx @@ -23,7 +23,7 @@ const persistableStateAttachmentTypeRegistry = new PersistableStateAttachmentTyp describe('use cases add to new case flyout hook', () => { const dispatch = jest.fn(); - let wrapper: FC; + let wrapper: FC>; beforeEach(() => { dispatch.mockReset(); wrapper = ({ children }) => { diff --git a/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx b/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx index f94cf78420744..9ac7658547725 100644 --- a/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx +++ b/x-pack/plugins/cases/public/components/create/sync_alerts_toggle.test.tsx @@ -19,7 +19,7 @@ import { schema } from './schema'; describe('SyncAlertsToggle', () => { let globalForm: FormHook; - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm({ defaultValue: { syncAlerts: true }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/tags.test.tsx b/x-pack/plugins/cases/public/components/create/tags.test.tsx index 0329a3875fcff..ed78d78928f0e 100644 --- a/x-pack/plugins/cases/public/components/create/tags.test.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.test.tsx @@ -29,7 +29,7 @@ describe('Tags', () => { let globalForm: FormHook; let appMockRender: AppMockRenderer; - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm({ defaultValue: { tags: [] }, schema: { diff --git a/x-pack/plugins/cases/public/components/create/title.test.tsx b/x-pack/plugins/cases/public/components/create/title.test.tsx index e592654176ac9..382ee67cc494c 100644 --- a/x-pack/plugins/cases/public/components/create/title.test.tsx +++ b/x-pack/plugins/cases/public/components/create/title.test.tsx @@ -19,7 +19,7 @@ import { schema } from './schema'; describe('Title', () => { let globalForm: FormHook; - const MockHookWrapperComponent: FC = ({ children }) => { + const MockHookWrapperComponent: FC> = ({ children }) => { const { form } = useForm({ defaultValue: { title: 'My title' }, schema: { diff --git a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx index 12f7afb64be14..3600a247540f5 100644 --- a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx @@ -29,7 +29,9 @@ const patchComment = jest.fn(); const clearDraftComment = jest.fn(); const openLensModal = jest.fn(); -const wrapper: FC = ({ children }) => {children}; +const wrapper: FC> = ({ children }) => ( + {children} +); describe('useUserActionsHandler', () => { beforeAll(() => { diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx index c21890c098dc8..6f828927b6fa6 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx +++ b/x-pack/plugins/cases/public/components/visualizations/actions/__mocks__/action_wrapper.tsx @@ -10,6 +10,6 @@ import React from 'react'; export const ActionWrapper = jest .fn() - .mockImplementation(({ children }: PropsWithChildren) => ( + .mockImplementation(({ children }: PropsWithChildren) => (
    {children}
    )); diff --git a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx index 6fb3d24c68836..07d05f292d722 100644 --- a/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx +++ b/x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.test.tsx @@ -47,7 +47,7 @@ jest.mock('../../../client/helpers/can_use_cases', () => { jest.mock('@kbn/kibana-react-plugin/public', () => ({ KibanaThemeProvider: jest .fn() - .mockImplementation(({ children }: PropsWithChildren) => <>{children}), + .mockImplementation(({ children }: PropsWithChildren) => <>{children}), })); jest.mock('@kbn/react-kibana-mount', () => ({ diff --git a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx index 1329413685c4c..6f7540eafa80e 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx @@ -17,7 +17,7 @@ import { useToasts } from '../common/lib/kibana'; jest.mock('./api'); jest.mock('../common/lib/kibana'); -const wrapper: FC = ({ children }) => { +const wrapper: FC> = ({ children }) => { const queryClient = new QueryClient({ defaultOptions: { queries: { diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx index b0a2ca904af31..3cda384f1c63c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx @@ -19,7 +19,9 @@ import { CaseMetricsFeature } from '../../common/types/api'; jest.mock('./api'); jest.mock('../common/lib/kibana'); -const wrapper: FC = ({ children }) => {children}; +const wrapper: FC> = ({ children }) => ( + {children} +); describe('useGetCaseMetrics', () => { const abortCtrl = new AbortController(); diff --git a/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx b/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx index 23f080bcee04b..352764b563952 100644 --- a/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx +++ b/x-pack/plugins/cases/public/mocks/mock_cases_context.tsx @@ -8,7 +8,7 @@ import type { FC, PropsWithChildren } from 'react'; import React from 'react'; -export const mockCasesContext: FC = (props) => { +export const mockCasesContext: FC> = (props) => { return <>{props?.children ?? null}; }; mockCasesContext.displayName = 'CasesContextMock'; diff --git a/x-pack/plugins/cloud/public/mocks.tsx b/x-pack/plugins/cloud/public/mocks.tsx index cd95bd783545e..8bd4a933a0f1b 100644 --- a/x-pack/plugins/cloud/public/mocks.tsx +++ b/x-pack/plugins/cloud/public/mocks.tsx @@ -35,7 +35,7 @@ function createSetupMock(): jest.Mocked { }; } -const getContextProvider: () => FC = +const getContextProvider: () => FC> = () => ({ children }) => <>{children}; diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index a210274b86252..f0a561194b562 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -56,7 +56,7 @@ export class CloudPlugin implements Plugin { private readonly config: CloudConfigType; private readonly isCloudEnabled: boolean; private readonly isServerlessEnabled: boolean; - private readonly contextProviders: Array> = []; + private readonly contextProviders: Array>> = []; private readonly logger: Logger; constructor(private readonly initializerContext: PluginInitializerContext) { @@ -112,7 +112,7 @@ export class CloudPlugin implements Plugin { // Nest all the registered context providers under the Cloud Services Provider. // This way, plugins only need to require Cloud's context provider to have all the enriched Cloud services. - const CloudContextProvider: FC = ({ children }) => { + const CloudContextProvider: FC> = ({ children }) => { return ( <> {this.contextProviders.reduce( diff --git a/x-pack/plugins/cloud/public/types.ts b/x-pack/plugins/cloud/public/types.ts index b154c065e5b20..8de4f226beea4 100644 --- a/x-pack/plugins/cloud/public/types.ts +++ b/x-pack/plugins/cloud/public/types.ts @@ -11,7 +11,7 @@ export interface CloudStart { /** * A React component that provides a pre-wired `React.Context` which connects components to Cloud services. */ - CloudContextProvider: FC; + CloudContextProvider: FC>; /** * `true` when Kibana is running on Elastic Cloud. */ diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx index f6d66f09e23a0..6331b82951bf0 100644 --- a/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/.storybook/decorator.tsx @@ -27,7 +27,7 @@ const services: CloudChatServices = { }, }; -export const getCloudContextProvider: () => FC = +export const getCloudContextProvider: () => FC> = () => ({ children }) => {children}; diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx index b9a3f7e8420be..abd43f0c87d6b 100644 --- a/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/public/components/chat/when_idle.tsx @@ -21,7 +21,7 @@ export function whenIdle(doWork: () => void) { /** * Postpone rendering of children until the page is loaded and browser is idle. */ -export const WhenIdle: FC = ({ children }) => { +export const WhenIdle: FC> = ({ children }) => { const [idleFired, setIdleFired] = React.useState(false); React.useEffect(() => { diff --git a/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx index 20d0be66c3a7c..d7dcb4763b67d 100755 --- a/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_chat/public/plugin.tsx @@ -58,7 +58,7 @@ export class CloudChatPlugin implements Plugin = ({ children }) => { + const CloudChatContextProvider: FC> = ({ children }) => { // There's a risk that the request for chat config will take too much time to complete, and the provider // will maintain a stale value. To avoid this, we'll use an Observable. const chatConfig = useObservable(this.chatConfig$, undefined); diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx index 37ddb8f3b5e9d..b967384161949 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/additional_controls.tsx @@ -13,7 +13,7 @@ import { useStyles } from './use_styles'; import { getAbbreviatedNumber } from '../../common/utils/get_abbreviated_number'; import { CSP_FIELDS_SELECTOR_OPEN_BUTTON } from '../test_subjects'; -const GroupSelectorWrapper: FC = ({ children }) => { +const GroupSelectorWrapper: FC> = ({ children }) => { const styles = useStyles(); return ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index 89b82b17d3187..d81b834f9c933 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -36,7 +36,9 @@ const queryClient = new QueryClient({ }); const getWrapper = - ({ canUpdate = true }: { canUpdate: boolean } = { canUpdate: true }): FC => + ( + { canUpdate = true }: { canUpdate: boolean } = { canUpdate: true } + ): FC> => ({ children }) => { const coreStart = coreMock.createStart(); const core = { diff --git a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts index aced694ff4172..2ea33df51463c 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts @@ -7,4 +7,4 @@ import { FC, PropsWithChildren } from 'react'; -declare const AutoFollowPatternDeleteProvider: FC; +declare const AutoFollowPatternDeleteProvider: FC>; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx index 6988fcecd29d6..86e85fb1cb87f 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx @@ -39,7 +39,7 @@ export const FileDataVisualizer: FC = ({ getAdditionalLinks, resultLinks fieldFormats, }; - const EmptyContext: FC = ({ children }) => <>{children}; + const EmptyContext: FC> = ({ children }) => <>{children}; const CloudContext = cloud?.CloudContextProvider || EmptyContext; return ( diff --git a/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx b/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx index 62b8d4a535235..762b3b4f0812d 100644 --- a/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx +++ b/x-pack/plugins/data_visualizer/public/lazy_load_bundle/component_wrapper.tsx @@ -11,7 +11,7 @@ import { EuiErrorBoundary, EuiSkeletonText } from '@elastic/eui'; import type { ResultLinks } from '../../common/app'; import type { DataDriftDetectionAppStateProps } from '../application/data_drift/data_drift_app_state'; -const LazyWrapper: FC = ({ children }) => ( +const LazyWrapper: FC> = ({ children }) => ( }>{children} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx index 997723dfa7924..9551e78b40095 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx @@ -124,7 +124,7 @@ export const ApiLogFlyout: React.FC = () => { ); }; -export const ApiLogHeading: FC = ({ children }) => ( +export const ApiLogHeading: FC> = ({ children }) => (

    {children}

    diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx index bfb67ec07bac5..6e613f0e9f106 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx @@ -10,7 +10,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -export const EmptySearchApplicationsPrompt: FC = ({ children }) => { +export const EmptySearchApplicationsPrompt: FC> = ({ children }) => { return ( = ({ children }) => { +export const ConnectorSyncRulesForm: FC> = ({ children }) => { const { saveDraftFilteringRules, setIsEditing } = useActions(ConnectorFilteringLogic); const { hasJsonValidationError, isEditing, isLoading } = useValues(ConnectorFilteringLogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx index 90f59d32a2787..a164e7605a4bf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx @@ -38,7 +38,7 @@ export const InferenceConfiguration: React.FC = () => { } }; -const InferenceConfigurationWrapper: FC = ({ children }) => { +const InferenceConfigurationWrapper: FC> = ({ children }) => { return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index c6763a6c97ad7..1a06537bb6020 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -92,7 +92,7 @@ export const renderApp = ( const productAccess = access || noProductAccess; const productFeatures = features ?? { ...DEFAULT_PRODUCT_FEATURES }; - const EmptyContext: FC = ({ children }) => <>{children}; + const EmptyContext: FC> = ({ children }) => <>{children}; const CloudContext = cloud?.CloudContextProvider || EmptyContext; resetContext({ createStore: true }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx index 95afb29db1675..30896ea9ae521 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx @@ -14,7 +14,7 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FLASH_MESSAGE_TYPES } from './constants'; import { FlashMessagesLogic } from './flash_messages_logic'; -export const FlashMessages: FC = ({ children }) => { +export const FlashMessages: FC> = ({ children }) => { const { messages } = useValues(FlashMessagesLogic); return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx index da2d5702850f9..394da346b2b7c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/endpoints_header_action.tsx @@ -39,7 +39,7 @@ import { KibanaLogic } from '../kibana'; import { EndpointIcon } from './endpoint_icon'; -export const EndpointsHeaderAction: FC = ({ children }) => { +export const EndpointsHeaderAction: FC> = ({ children }) => { const [isPopoverOpen, setPopoverOpen] = useState(false); const { cloud, esConfig, navigateToUrl } = useValues(KibanaLogic); const { makeRequest } = useActions(FetchApiKeysAPILogic); diff --git a/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx b/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx index 3d1121e3ccb57..a9f1928984217 100644 --- a/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx +++ b/x-pack/plugins/ml/public/application/components/field_stats_flyout/field_stats_flyout_provider.tsx @@ -22,7 +22,7 @@ import { MLFieldStatsFlyoutContext } from './use_field_stats_flytout_context'; import { PopulatedFieldsCacheManager } from './populated_fields/populated_fields_cache_manager'; export const FieldStatsFlyoutProvider: FC<{ - children: React.ReactNode; + children?: React.ReactNode; dataView: DataView; fieldStatsServices: FieldStatsServices; timeRangeMs?: TimeRangeMs; diff --git a/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx b/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx index d1b43e6037a19..30cb1ff9c6c0a 100644 --- a/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx +++ b/x-pack/plugins/ml/public/application/components/page_header/page_header.tsx @@ -14,7 +14,7 @@ import { MlPageControlsContext } from '../ml_page/ml_page'; /** * Component for setting the page header content. */ -export const MlPageHeader: FC = ({ children }) => { +export const MlPageHeader: FC> = ({ children }) => { const { headerPortal, setIsHeaderMounted } = useContext(MlPageControlsContext); useEffect(() => { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx index e543c862e8057..db6f5bb955e99 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/advanced_detector_modal/descriptions.tsx @@ -13,7 +13,7 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiFlexGroup, EuiFlexItem } from '@e import { FunctionHelpPopover } from './function_help'; -export const AggDescription = memo(({ children }) => { +export const AggDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.aggSelect.title', { @@ -46,7 +46,7 @@ export const AggDescription = memo(({ children }) => { ); }); -export const FieldDescription = memo(({ children }) => { +export const FieldDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.fieldSelect.title', { @@ -70,7 +70,7 @@ export const FieldDescription = memo(({ children }) => { ); }); -export const ByFieldDescription = memo(({ children }) => { +export const ByFieldDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.byFieldSelect.title', { @@ -94,7 +94,7 @@ export const ByFieldDescription = memo(({ children }) => { ); }); -export const OverFieldDescription = memo(({ children }) => { +export const OverFieldDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.overFieldSelect.title', { @@ -118,7 +118,7 @@ export const OverFieldDescription = memo(({ children }) => { ); }); -export const PartitionFieldDescription = memo(({ children }) => { +export const PartitionFieldDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.partitionFieldSelect.title', { @@ -142,7 +142,7 @@ export const PartitionFieldDescription = memo(({ children }) ); }); -export const ExcludeFrequentDescription = memo(({ children }) => { +export const ExcludeFrequentDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.excludeFrequent.title', { @@ -166,7 +166,7 @@ export const ExcludeFrequentDescription = memo(({ children }) ); }); -export const DescriptionDescription = memo(({ children }) => { +export const DescriptionDescription = memo>(({ children }) => { const title = i18n.translate( 'xpack.ml.newJob.wizard.pickFieldsStep.advancedDetectorModal.description.title', { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx index 681145a1f7de0..377a71ab80095 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_partition_field/description.tsx @@ -10,11 +10,7 @@ import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; - -interface Props { - children: React.ReactNode; -} -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.perPartitionCategorization.enable.title', { defaultMessage: 'Per-partition categorization', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx index 7fc0189dc7c81..801c05c71d822 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/field_examples.tsx @@ -73,6 +73,6 @@ export const FieldExamples: FC = ({ fieldExamples }) => { ); }; -const Token: FC = ({ children }) => ( +const Token: FC> = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx index 8edca937c5042..489fa99a4bbff 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/geo_field/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.geoField.title', { defaultMessage: 'Geo field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx index 5ff7b0a385174..8652984566b17 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/influencers/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.influencers.title', { defaultMessage: 'Influencers', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx index f8c237696024b..04fb60e5fe681 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/population_field/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.populationField.title', { defaultMessage: 'Population field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx index 58c269ae6e6e3..0ea99ed45fa1b 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/rare_field/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.splitRareField.title', { defaultMessage: 'Rare field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx index 247dea4716b91..2dc6371010bdc 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/sparse_data/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.sparseData.title', { defaultMessage: 'Sparse data', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx index e8980258477eb..1d87ed4f9253d 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/split_field/description.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; -export const Description = memo(({ children }) => { +export const Description = memo>(({ children }) => { const title = i18n.translate('xpack.ml.newJob.wizard.pickFieldsStep.splitField.title', { defaultMessage: 'Split field', }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx index e8d46428a6401..35a337fc1be2d 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/summary_step/components/common.tsx @@ -50,6 +50,6 @@ export const DatafeedSectionTitle: FC = () => ( ); -export const Italic: FC = ({ children }) => ( +export const Italic: FC> = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx index 40ce2f2d2ffb5..dac36551377be 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx @@ -57,7 +57,7 @@ const getMockedDatePickeDependencies = () => { } as unknown as DatePickerDependencies; }; -const Wrapper: FC = ({ children }) => ( +const Wrapper: FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx index 69e4285647bdb..8119c7305c0fd 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx @@ -25,7 +25,7 @@ jest.mock('../../../timeseriesexplorer', () => ({ })); jest.mock('../../../timeseriesexplorer/timeseriesexplorer_page', () => ({ - TimeSeriesExplorerPage: jest.fn(({ children }: PropsWithChildren) => { + TimeSeriesExplorerPage: jest.fn(({ children }: PropsWithChildren) => { return <>{children}; }), })); diff --git a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx index f175ef877a660..e82e14350cc7d 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/chart_preview_helper.tsx @@ -38,7 +38,7 @@ export const getDomain = (series: Array<{ name?: string; data: Coordinate[] }>) }; }; -const EmptyContainer: FC = ({ children }) => ( +const EmptyContainer: FC> = ({ children }) => (
    = ({ children }) => ( +const wrapper: FC> = ({ children }) => ( { return { yMin: min || 0, yMax: max || 0, xMin: minTimestamp, xMax: maxTimestamp }; }; -export const EmptyContainer: FC = ({ children }) => ( +export const EmptyContainer: FC> = ({ children }) => (
    = ({ children }) => (
    ); -export const ChartContainer: FC = ({ children }) => ( +export const ChartContainer: FC> = ({ children }) => (
    = ({ children }) => { +export const SourceStatusWrapper: FC> = ({ children }) => { const { load, isLoading, hasFailedLoading, isUninitialized } = useLogViewContext(); return ( diff --git a/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx b/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx index ddfc58bce784f..216a5fcb06bf9 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/loading_overlay_wrapper.tsx @@ -24,7 +24,7 @@ export const LoadingOverlayWrapper: React.FC< ); }; -const Overlay: FC = ({ children }) => ( +const Overlay: FC> = ({ children }) => ( {children ? children : } ); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 5cab07479a19b..bd1ae5d9c8336 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -16,7 +16,7 @@ import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; import { useLogMlJobIdFormatsShimContext } from '../shared/use_log_ml_job_id_formats_shim'; -export const LogEntryCategoriesPageProviders: FC = ({ children }) => { +export const LogEntryCategoriesPageProviders: FC> = ({ children }) => { const { hasFailedLoading, isLoading, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 1e31b28f87b0f..d2cf0f3e613ee 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -18,7 +18,7 @@ import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; import { useLogMlJobIdFormatsShimContext } from '../shared/use_log_ml_job_id_formats_shim'; -export const LogEntryRatePageProviders: FC = ({ children }) => { +export const LogEntryRatePageProviders: FC> = ({ children }) => { const { hasFailedLoading, isLoading, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx index d2b745127862b..4e5e9ffc74abd 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_providers.tsx @@ -16,7 +16,7 @@ import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analy import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context'; -export const LogsPageProviders: FC = ({ children }) => { +export const LogsPageProviders: FC> = ({ children }) => { const { services: { notifications: { toasts: toastsService }, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx index a9415f331fef1..a8fd0cecf448b 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_providers.tsx @@ -24,7 +24,7 @@ import { LogViewConfigurationProvider } from '../../../containers/logs/log_view_ import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; -const ViewLogInContext: FC = ({ children }) => { +const ViewLogInContext: FC> = ({ children }) => { const { startTimestamp, endTimestamp } = useLogPositionStateContext(); const { logViewReference } = useLogViewContext(); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx index 3c1217889e28c..139d318618f73 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx @@ -70,7 +70,7 @@ const createProviderWrapper = () => { history.push(INITIAL_URL); const scopedHistory = new CoreScopedHistory(history, INITIAL_URL); - const ProviderWrapper: FC = ({ children }) => { + const ProviderWrapper: FC> = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx index f68868a556316..27647088c9a53 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx @@ -36,7 +36,7 @@ const queryClient = new QueryClient({ }); const renderUseMetricsExplorerDataHook = () => { - const wrapper: FC = ({ children }) => { + const wrapper: FC> = ({ children }) => { const services = { http: { post: mockedFetch, diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx index 2901139884fa8..71cf60db48068 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx @@ -19,7 +19,7 @@ coreStartMock.application.getUrlForApp.mockImplementation((app, options) => { return `/test-basepath/s/test-space/app/${app}${options?.path}`; }); -const ProviderWrapper: FC = ({ children }) => { +const ProviderWrapper: FC> = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx index 8f360c5c48618..72c6c742ea29e 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx @@ -11,7 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; /** * Create a separator with a text on the right side */ -export const LogTextSeparator: FC = ({ children }) => { +export const LogTextSeparator: FC> = ({ children }) => { return ( {children} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_conversation.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_conversation.test.tsx index 3a39aa05457fe..aa5c659baf882 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_conversation.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_conversation.test.tsx @@ -85,7 +85,7 @@ describe('useConversation', () => { beforeEach(() => { jest.clearAllMocks(); - wrapper = ({ children }: PropsWithChildren) => ( + wrapper = ({ children }: PropsWithChildren) => ( {children} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx index 6ecc80e587a7d..980d76f76c868 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/wrappers/service_allowed_wrapper.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiEmptyPrompt, EuiLoadingLogo } from '@elastic/eui'; import { useSyntheticsServiceAllowed } from '../../../hooks/use_service_allowed'; -export const ServiceAllowedWrapper: FC = ({ children }) => { +export const ServiceAllowedWrapper: FC> = ({ children }) => { const { isAllowed, signupUrl, loading } = useSyntheticsServiceAllowed(); if (loading) { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx index 48d4410b47514..499529e8523be 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_pending_wrapper.tsx @@ -15,7 +15,7 @@ import { resetMonitorLastRunAction } from '../../state'; import { useMonitorLatestPing } from './hooks/use_monitor_latest_ping'; import { useSyntheticsRefreshContext } from '../../contexts'; -export const MonitorPendingWrapper: FC = ({ children }) => { +export const MonitorPendingWrapper: FC> = ({ children }) => { const dispatch = useDispatch(); const history = useHistory(); const currentLocation = useLocation(); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx index beddff01404e6..b4e1a4bf41aa3 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx @@ -34,7 +34,7 @@ const defaultContext: SyntheticsRefreshContext = { export const SyntheticsRefreshContext = createContext(defaultContext); -export const SyntheticsRefreshContextProvider: FC = ({ children }) => { +export const SyntheticsRefreshContextProvider: FC> = ({ children }) => { const [lastRefresh, setLastRefresh] = useState(Date.now()); const refreshPaused = useSelector(selectRefreshPaused); diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx index f353d85d96bf5..9df12c1432445 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/monitor_tags.test.tsx @@ -165,7 +165,7 @@ describe('MonitorTags component', () => { it('expand tag show tags on click', () => { summaryPing.state.summaryPings[0].tags = ['red', 'green', 'blue', 'black', 'purple', 'yellow']; - const Wrapper: FC = ({ children }) => ( + const Wrapper: FC> = ({ children }) => ( {children} ); render(, { wrapper: Wrapper }); diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx index 130b9ab449644..b2083d9c1f38d 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/contexts/uptime_refresh_context.tsx @@ -21,7 +21,7 @@ const defaultContext: UptimeRefreshContext = { export const UptimeRefreshContext = createContext(defaultContext); -export const UptimeRefreshContextProvider: FC = ({ children }) => { +export const UptimeRefreshContextProvider: FC> = ({ children }) => { const [lastRefresh, setLastRefresh] = useState(Date.now()); const refreshApp = () => { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx index 79cf01afc6670..9fd0a07033120 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/use_overview_filter_check.test.tsx @@ -12,7 +12,7 @@ import * as reactRedux from 'react-redux'; import { useOverviewFilterCheck } from './use_overview_filter_check'; import { MockRouter } from '../lib/helper/rtl_helpers'; -function getWrapper(customSearch?: string): FC { +function getWrapper(customSearch?: string): FC> { return ({ children }) => { const { location, ...rest } = createMemoryHistory(); return ( diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx index 4a5abb90dce72..e8956aab0dca9 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_results/test_utils.tsx @@ -78,4 +78,6 @@ export const getMockedKibanaConfig = (permissionType: unknown) => }, } as unknown as ReturnType); -export const mockCasesContext: FC = (props) => <>{props?.children ?? null}; +export const mockCasesContext: FC> = (props) => ( + <>{props?.children ?? null} +); diff --git a/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx b/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx index 336323a7e56f9..a6ac75b330152 100644 --- a/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx +++ b/x-pack/plugins/reporting/public/lib/ilm_policy_status_context.tsx @@ -20,7 +20,7 @@ interface ContextValue { const IlmPolicyStatusContext = createContext(undefined); -export const IlmPolicyStatusContextProvider: FC = ({ children }) => { +export const IlmPolicyStatusContextProvider: FC> = ({ children }) => { const { isLoading, data, resendRequest: recheckStatus } = useCheckIlmPolicyStatus(); return ( diff --git a/x-pack/plugins/search_notebooks/public/components/title_panel.tsx b/x-pack/plugins/search_notebooks/public/components/title_panel.tsx index 86a22d59a8178..0be5606b6521f 100644 --- a/x-pack/plugins/search_notebooks/public/components/title_panel.tsx +++ b/x-pack/plugins/search_notebooks/public/components/title_panel.tsx @@ -7,7 +7,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { EuiHorizontalRule, EuiPanel, EuiText } from '@elastic/eui'; -export const TitlePanel: FC = ({ children }) => ( +export const TitlePanel: FC> = ({ children }) => ( <> diff --git a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx index d70b2cfc77005..194b451ccd1fb 100644 --- a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx +++ b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_sidebar.test.tsx @@ -19,7 +19,7 @@ jest.mock('../../hooks/use_query_indices', () => ({ useQueryIndices: jest.fn(), })); -const Wrapper: FC = ({ children }) => { +const Wrapper: FC> = ({ children }) => { return ( <> {children} diff --git a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx index 54f2610e453ac..bb7d03a8cae72 100644 --- a/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx +++ b/x-pack/plugins/search_playground/public/components/sources_panel/sources_panel_for_start_chat.test.tsx @@ -28,7 +28,7 @@ jest.mock('../../hooks/use_kibana', () => ({ })), })); -const Wrapper: FC = ({ children }) => { +const Wrapper: FC> = ({ children }) => { return ( <> {children} diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx index 2bbcf4b03623e..01d6fc95afcc1 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx @@ -7,7 +7,8 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { mount } from 'enzyme'; -import React, { FC, PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren } from 'react'; +import React from 'react'; import { coreMock, scopedHistoryMock } from '@kbn/core/public/mocks'; @@ -24,7 +25,7 @@ const coreStart = coreMock.createStart(); let history = scopedHistoryMock.create(); const authc = securityMock.createSetup().authc; -const wrapper: FC = ({ children }) => ( +const wrapper: FC> = ({ children }) => ( * ``` */ -export const Breadcrumb: FunctionComponent = ({ children, ...breadcrumb }) => { +export const Breadcrumb: FC> = ({ children, ...breadcrumb }) => { const context = useContext(BreadcrumbsContext); const component = {children}; diff --git a/x-pack/plugins/security_solution/public/assistant/provider.tsx b/x-pack/plugins/security_solution/public/assistant/provider.tsx index a1be7d7888f05..8516ec455aac0 100644 --- a/x-pack/plugins/security_solution/public/assistant/provider.tsx +++ b/x-pack/plugins/security_solution/public/assistant/provider.tsx @@ -115,7 +115,7 @@ export const createConversations = async ( /** * This component configures the Elastic AI Assistant context provider for the Security Solution app. */ -export const AssistantProvider: FC = ({ children }) => { +export const AssistantProvider: FC> = ({ children }) => { const { http, notifications, diff --git a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx index e6e8222468bda..d4610d987c400 100644 --- a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React, { useCallback } from 'react'; import { EuiButton, EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; import type { Filter } from '@kbn/es-query'; diff --git a/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx b/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx index c04f8536c4eb8..f679eeab5d61c 100644 --- a/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/__mocks__/query_wrapper.tsx @@ -11,7 +11,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; export const createQueryWrapperMock = (): { queryClient: QueryClient; - wrapper: FC; + wrapper: FC>; } => { const queryClient = new QueryClient({ defaultOptions: { diff --git a/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx b/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx index 2982c7b87e3d6..923134a3d690e 100644 --- a/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/current_license/index.tsx @@ -13,7 +13,7 @@ import type { ILicense } from '@kbn/licensing-plugin/common/types'; import { licenseService } from '../../hooks/use_license'; import type { AppAction } from '../../store/actions'; -export const CurrentLicense = memo(({ children }) => { +export const CurrentLicense = memo>(({ children }) => { const dispatch = useDispatch>(); useEffect(() => { const subscription = licenseService diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx index 892154c03c2e8..e0ec353d680b9 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx @@ -17,7 +17,7 @@ import { timelineActions } from '../../../timelines/store'; * This component should be used above all routes, but below the Provider. * It dispatches actions when the URL is changed. */ -export const RouteCapture = memo(({ children }) => { +export const RouteCapture = memo>(({ children }) => { const location: AppLocation = useLocation(); const dispatch = useDispatch(); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx index 6c8980e012ed7..af878acd8b104 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx @@ -28,7 +28,7 @@ const UppercaseEuiTitle = styled(EuiTitle)` text-transform: uppercase; `; -const ThreatSummaryPanelTitle: FC = ({ children }) => ( +const ThreatSummaryPanelTitle: FC> = ({ children }) => (
    {children}
    diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx index 0e8183df7ff29..8d263b8e2efb1 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx @@ -15,7 +15,7 @@ const EventDetailsWidthContext = createContext(DEFAULT_WIDTH); export const useEventDetailsWidthContext = () => useContext(EventDetailsWidthContext); -export const EventDetailsWidthProvider = React.memo(({ children }) => { +export const EventDetailsWidthProvider = React.memo>(({ children }) => { const { ref, width } = useThrottledResizeObserver(); return ( diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx index 08d3fb6f2b757..8b98ffe3cf6ea 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/product_switch.tsx @@ -10,6 +10,6 @@ import React from 'react'; export const ProductSwitch = jest .fn() - .mockImplementation(({ children }: PropsWithChildren) => ( + .mockImplementation(({ children }: PropsWithChildren) => (
    {children}
    )); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx index fce63a07ce506..e297e119dfffe 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/__mocks__/toggle_panel.tsx @@ -10,6 +10,6 @@ import React from 'react'; export const TogglePanel = jest .fn() - .mockImplementation(({ children }: PropsWithChildren) => ( + .mockImplementation(({ children }: PropsWithChildren) => (
    {children}
    )); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx index 8fb9a9d9b0b3c..22a6a2a052885 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx @@ -30,7 +30,7 @@ export const MlCapabilitiesContext = React.createContext MlCapabilitiesContext.displayName = 'MlCapabilitiesContext'; -export const MlCapabilitiesProvider = React.memo(({ children }) => { +export const MlCapabilitiesProvider = React.memo>(({ children }) => { const [capabilities, setCapabilities] = useState( emptyMlCapabilitiesProvider ); diff --git a/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx b/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx index 65e35b1f42443..265e921f67f45 100644 --- a/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/security_route_page_wrapper/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { Redirect } from 'react-router-dom'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx index 06ce7a64c0ac5..ee783bcd19e3d 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx @@ -30,7 +30,7 @@ jest.mock('../lib/kibana', () => { }); const TestComponent = () =>
    {'TEST 1 2 3'}
    ; -const RenderWrapper: FC = ({ children }) => { +const RenderWrapper: FC> = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx index 45066b902873c..1f5a7c43b38b1 100644 --- a/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/storybook_providers.tsx @@ -94,7 +94,7 @@ const KibanaReactContext = createKibanaReactContext(coreMock); * It is a simplified version of TestProvidersComponent. * To reuse TestProvidersComponent here, we need to remove all references to jest from mocks. */ -export const StorybookProviders: FC = ({ children }) => { +export const StorybookProviders: FC> = ({ children }) => { const store = createMockStore(); return ( diff --git a/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx b/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx index e724f961625a7..54b194a2dcbae 100644 --- a/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/context/dashboard_context.tsx @@ -19,7 +19,7 @@ export interface DashboardContextType { const DashboardContext = React.createContext({ securityTags: null }); -export const DashboardContextProvider: FC = ({ children }) => { +export const DashboardContextProvider: FC> = ({ children }) => { const { tags, isLoading } = useFetchSecurityTags(); const securityTags = isLoading || !tags ? null : tags; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx index b21a51b22b44d..69503c7062372 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx @@ -146,7 +146,7 @@ const convertToDiffFile = (oldSource: string, newSource: string) => { return diffFile; }; -const CustomStyles: FC = ({ children }) => { +const CustomStyles: FC> = ({ children }) => { const { euiTheme } = useEuiTheme(); const customCss = css` diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx index c16e18f009dd9..826b4d483ace9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx @@ -64,7 +64,7 @@ describe('Rule upgrade workflow: viewing rule changes in JSON diff view', () => delete oldRule.license; newRule.license = 'GPLv3'; - const ThemeWrapper: FC = ({ children }) => ( + const ThemeWrapper: FC> = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx index dc783c15f79f6..7c7125a36dc5d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx @@ -101,7 +101,7 @@ const tabPaddingClassName = css` padding: 0 ${euiThemeVars.euiSizeM} ${euiThemeVars.euiSizeXL} ${euiThemeVars.euiSizeM}; `; -export const TabContentPadding: FC = ({ children }) => ( +export const TabContentPadding: FC> = ({ children }) => (
    {children}
    ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx index 6be5fff720734..c0112f13b776a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx @@ -15,7 +15,7 @@ import { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; import type { DryRunResult } from './types'; import { BulkActionTypeEnum } from '../../../../../../common/api/detection_engine/rule_management'; -const Wrapper: FC = ({ children }) => { +const Wrapper: FC> = ({ children }) => { return ( <>{children} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx index cc1e9030b0ff6..09caca91b30f3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx @@ -42,7 +42,7 @@ describe('useExecutionEvents', () => { }, }, }); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx index 2178401fa1f37..45c7eaca3599e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx @@ -37,7 +37,7 @@ describe('useExecutionResults', () => { }, }, }); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx b/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx index fc9b3c35a5b48..891d85175aa4d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/host_isolation/use_host_isolation_action.test.tsx @@ -34,7 +34,7 @@ describe('useHostIsolationAction', () => { ])('works with %s hook', (name, hook) => { const createReactQueryWrapper = () => { const queryClient = new QueryClient(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx index da29cb140ac24..74791dfff2032 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx @@ -36,7 +36,7 @@ describe('useInstalledIntegrations', () => { }, }, }); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); return wrapper; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx index 8cf79337ac84b..45291cb5d0315 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_execution_status/rule_status_failed_callout.test.tsx @@ -48,7 +48,7 @@ const queryClient = new QueryClient({ }, }); -const ContextWrapper: FC = ({ children }) => ( +const ContextWrapper: FC> = ({ children }) => ( = ({ children }) => ( +const ProviderComponent: FC> = ({ children }) => ( {children} ); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx index d874eccae5c4c..839573da18c45 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/components/exception_items_summary.test.tsx @@ -28,7 +28,7 @@ describe('Fleet event filters card', () => { const renderComponent: ( stats: GetExceptionSummaryResponse ) => reactTestingLibrary.RenderResult = (stats) => { - const Wrapper: React.FC = ({ children }) => ( + const Wrapper: React.FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx index 26aaa3656147e..79bafb3735426 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_agent_tamper_protection_extension.tsx @@ -9,12 +9,14 @@ import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { useUpsellingComponent } from '../../../../../common/hooks/use_upselling'; -export const EndpointAgentTamperProtectionExtension = memo(({ children }) => { - const Component = useUpsellingComponent('endpoint_agent_tamper_protection'); - if (!Component) { - return <>{children}; +export const EndpointAgentTamperProtectionExtension = memo>( + ({ children }) => { + const Component = useUpsellingComponent('endpoint_agent_tamper_protection'); + if (!Component) { + return <>{children}; + } + return ; } - return ; -}); +); EndpointAgentTamperProtectionExtension.displayName = 'EndpointAgentTamperProtectionExtension'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx index e90b15e760283..7bad12cc0be9d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx @@ -83,7 +83,7 @@ export const createFleetContextRendererMock = (): AppContextTestRender => { additionalMiddleware: [mockedContext.middlewareSpy.actionSpyMiddleware], }); - const Wrapper: RenderOptions['wrapper'] = ({ children }: PropsWithChildren) => { + const Wrapper: RenderOptions['wrapper'] = ({ children }: PropsWithChildren) => { useEffect(() => { return () => { // When the component un-mounts, reset the Experimental features since diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx index bf29bef12d94a..b0502786ea05a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { PropsWithChildren } from 'react'; import React, { memo } from 'react'; import { EuiSpacer, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -110,7 +111,7 @@ export const PolicySettingsForm = memo((props) => { }); PolicySettingsForm.displayName = 'PolicySettingsForm'; -const FormSectionTitle = memo(({ children }) => { +const FormSectionTitle = memo>(({ children }) => { return (

    {children}

    diff --git a/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx index e9252405fbb0f..e40a2b383196a 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/landing.test.tsx @@ -16,7 +16,7 @@ jest.mock('../../common/components/landing_page'); jest.mock('../../common/components/page_wrapper', () => ({ SecuritySolutionPageWrapper: jest .fn() - .mockImplementation(({ children }: PropsWithChildren) =>
    {children}
    ), + .mockImplementation(({ children }: PropsWithChildren) =>
    {children}
    ), })); const history = createBrowserHistory(); describe('LandingPage', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx index efe693abe24ad..4c9c40712d719 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx @@ -6,6 +6,7 @@ */ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import type { PropsWithChildren } from 'react'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { isEventBuildingBlockType } from '@kbn/securitysolution-data-table'; @@ -75,10 +76,12 @@ interface Props { const emptyNotes: string[] = []; -const EventsTrSupplementContainerWrapper = React.memo(({ children }) => { - const width = useEventDetailsWidthContext(); - return {children}; -}); +const EventsTrSupplementContainerWrapper = React.memo>( + ({ children }) => { + const width = useEventDetailsWidthContext(); + return {children}; + } +); EventsTrSupplementContainerWrapper.displayName = 'EventsTrSupplementContainerWrapper'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx index 7168588bb9599..9b87b6ececbae 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx @@ -85,7 +85,7 @@ describe('useSessionView with active timeline and a session id and graph event i let setTimelineFullScreen: jest.Mock; let setGlobalFullScreen: jest.Mock; let kibana: ReturnType; - const Wrapper = memo(({ children }) => { + const Wrapper = memo>(({ children }) => { kibana = useKibana(); return {children}; }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx index e7688e9a7db95..00f745e962066 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx @@ -136,7 +136,7 @@ const TestComponent = (props: Partial>) = const customStore = createMockStore(); -const TestProviderWrapperWithCustomStore: FC = ({ children }) => { +const TestProviderWrapperWithCustomStore: FC> = ({ children }) => { return {children}; }; diff --git a/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx b/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx index 100295a717464..97f33812bf8d0 100644 --- a/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/services/__mocks__/index.tsx @@ -12,7 +12,7 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { mockServices } from './services.mock'; import { NavigationProvider } from '@kbn/security-solution-navigation'; -export const ServicesProvider: FC = ({ children }) => ( +export const ServicesProvider: FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx index 924bce20ffbac..dca8f767750ec 100644 --- a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FC, PropsWithChildren } from 'react'; import { EuiSpacer, EuiSplitPanel, EuiTitle } from '@elastic/eui'; export interface IndexOverviewPanelProps { @@ -34,7 +34,7 @@ export const IndexOverviewPanel: FC> ); -export const IndexOverviewPanelStat: FC = ({ children }) => ( +export const IndexOverviewPanelStat: FC> = ({ children }) => (

    {children}

    diff --git a/x-pack/plugins/serverless_search/public/application/components/overview.tsx b/x-pack/plugins/serverless_search/public/application/components/overview.tsx index 4fbef0277222a..3fcf7bc2d5cd6 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview.tsx @@ -484,7 +484,7 @@ const OverviewFooter = () => { ); }; -const FooterButtonContainer: FC = ({ children }) => ( +const FooterButtonContainer: FC> = ({ children }) => ( diff --git a/x-pack/plugins/serverless_search/public/test/test_utils.tsx b/x-pack/plugins/serverless_search/public/test/test_utils.tsx index 01cba69d3cc08..4912ddd5c6484 100644 --- a/x-pack/plugins/serverless_search/public/test/test_utils.tsx +++ b/x-pack/plugins/serverless_search/public/test/test_utils.tsx @@ -32,7 +32,7 @@ const queryClient = new QueryClient({ }, }); -const AllTheProviders: FC = ({ children }) => { +const AllTheProviders: FC> = ({ children }) => { return ( diff --git a/x-pack/plugins/spaces/public/spaces_context/context.tsx b/x-pack/plugins/spaces/public/spaces_context/context.tsx index 5fe227c37e43c..9bf96df7c2d20 100644 --- a/x-pack/plugins/spaces/public/spaces_context/context.tsx +++ b/x-pack/plugins/spaces/public/spaces_context/context.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React, { FC, PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren } from 'react'; +import React from 'react'; import type { CoreStart } from '@kbn/core/public'; @@ -32,7 +33,7 @@ export const createSpacesReactContext = >( spacesDataPromise, services, }; - const Provider: FC = ({ children }) => + const Provider: FC> = ({ children }) => createElement(context.Provider as React.ComponentType, { value, children }); return { diff --git a/x-pack/plugins/spaces/public/spaces_context/types.ts b/x-pack/plugins/spaces/public/spaces_context/types.ts index 0cac358333f88..54a312ef97bbb 100644 --- a/x-pack/plugins/spaces/public/spaces_context/types.ts +++ b/x-pack/plugins/spaces/public/spaces_context/types.ts @@ -21,7 +21,7 @@ export interface SpacesReactContextValue> { export interface SpacesReactContext> { value: SpacesReactContextValue; - Provider: React.FC; + Provider: React.FC>; Consumer: React.Consumer>; } diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx index b4457e55eda8a..30053119e50c1 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx @@ -11,7 +11,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import { SourceFields } from './source_fields_select'; import { SourceField } from '../es_query/types'; -const AppWrapper = React.memo(({ children }) => ( +const AppWrapper = React.memo>(({ children }) => ( {children} )); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx index 99af4c482f976..e7913a36dd6a1 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.test.tsx @@ -27,7 +27,7 @@ jest.mock('@kbn/text-based-editor', () => ({ const { fetchFieldsFromESQL } = jest.requireMock('@kbn/text-based-editor'); const { getFields } = jest.requireMock('@kbn/triggers-actions-ui-plugin/public'); -const AppWrapper = React.memo(({ children }) => ( +const AppWrapper = React.memo>(({ children }) => ( {children} )); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx index 6fad9c97abcfe..7b97495881331 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row_table.test.tsx @@ -10,7 +10,7 @@ import { render } from '@testing-library/react'; import { I18nProvider } from '@kbn/i18n-react'; import { TestQueryRowTable } from './test_query_row_table'; -const AppWrapper = React.memo(({ children }) => ( +const AppWrapper = React.memo>(({ children }) => ( {children} )); diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx index f396d6ae4711f..bc005bb0fad65 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard.tsx @@ -11,7 +11,7 @@ import { Paywall } from '../components/paywall'; import { useSecurityContext } from '../hooks/use_security_context'; import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugin_template_wrapper'; -export const EnterpriseGuard = memo(({ children }) => { +export const EnterpriseGuard = memo>(({ children }) => { const { licenseService } = useSecurityContext(); if (licenseService.isEnterprise()) { diff --git a/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx b/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx index ba12aafa51d27..bff41a2a4ef01 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/field_types_provider.tsx @@ -15,7 +15,7 @@ export const FieldTypesContext = createContext = ({ children }) => { +export const FieldTypesProvider: FC> = ({ children }) => { const { indexPattern } = useSourcererDataView(); // field name to field type map to allow the cell_renderer to format dates diff --git a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx index 106f8c367844c..32a37d572c062 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx @@ -8,7 +8,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { useSecurityContext } from '../hooks/use_security_context'; -export const FiltersGlobal: FC = ({ children }) => { +export const FiltersGlobal: FC> = ({ children }) => { const contextValue = useSecurityContext(); const Component = contextValue.getFiltersGlobalComponent(); diff --git a/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx b/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx index 836b9a650fd78..01cfe587bf199 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/inspector.tsx @@ -14,7 +14,7 @@ export interface InspectorContextValue { export const InspectorContext = createContext(undefined); -export const InspectorProvider: FC = ({ children }) => { +export const InspectorProvider: FC> = ({ children }) => { const inspectorAdapters = useMemo(() => ({ requests: new RequestAdapter() }), []); return ( diff --git a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx index c7c2c93e5e23a..72988f3397263 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard.tsx @@ -19,7 +19,7 @@ import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugi * If none are received, show the EmptyPage with a link to go install integrations. * While the indicators call and the integrations call are loading, display a loading screen. */ -export const IntegrationsGuard = memo(({ children }) => { +export const IntegrationsGuard = memo>(({ children }) => { const { isLoading: indicatorsTotalCountLoading, count: indicatorsTotalCount } = useIndicatorsTotalCount(); diff --git a/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx b/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx index 167f4bbbfeed6..0b37351c0bd22 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/security_solution_page_wrapper.tsx @@ -11,7 +11,7 @@ import { useSecurityContext } from '../hooks/use_security_context'; /** * Security solution page wrapper, with some extra styling etc. */ -export const SecuritySolutionPageWrapper: FC = ({ children }) => { +export const SecuritySolutionPageWrapper: FC> = ({ children }) => { const contextValue = useSecurityContext(); const Component = contextValue.getPageWrapper(); diff --git a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx index 6dd93abb6ccba..c56ebb122129a 100644 --- a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx @@ -138,7 +138,7 @@ export const mockedServices = { }, }; -export const TestProvidersComponent: FC = ({ children }) => ( +export const TestProvidersComponent: FC> = ({ children }) => ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx index 2fcbbdbd9795a..a9e6d604da4df 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx @@ -21,7 +21,7 @@ export interface BlockListContextValue { export const BlockListContext = createContext(undefined); -export const BlockListProvider: FC = ({ children }) => { +export const BlockListProvider: FC> = ({ children }) => { const [blockListIndicatorValue, setBlockListIndicatorValue] = useState(''); const context: BlockListContextValue = { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx index 43ebe7d510f54..7d4f7286d2558 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/filters.tsx @@ -16,7 +16,7 @@ import { /** * Container used to wrap components and share the {@link FilterManager} through React context. */ -export const IndicatorsFilters: FC = ({ children }) => { +export const IndicatorsFilters: FC> = ({ children }) => { const securityContext = useSecurityContext(); const { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx index 4f7b65864d96f..f2a7b566bd5d6 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx @@ -24,7 +24,7 @@ import { IndicatorsFilters } from '../containers/filters'; import { UpdateStatus } from '../../../components/update_status'; import { QueryBar } from '../../query_bar/components/query_bar'; -const IndicatorsPageProviders: FC = ({ children }) => ( +const IndicatorsPageProviders: FC> = ({ children }) => ( 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 902a98fe58549..4607129313c8c 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 @@ -48,7 +48,7 @@ const queryClient = new QueryClient(); describe('Transform: useIndexData()', () => { test('dataView set triggers loading', async () => { const mlShared = await getMlSharedImports(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx b/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx index 80bbdeb2bb601..7e5b38294b664 100644 --- a/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/edit_transform/state_management/edit_transform_flyout_state.test.tsx @@ -21,7 +21,7 @@ import { useIsFormValid } from './selectors/is_form_valid'; describe('Transform: useEditTransformFlyoutActions/Selector()', () => { it('field updates should trigger form validation', () => { const transformConfigMock = getTransformConfigMock(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx index ac8eeb9ebce71..02064c76c95ce 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx @@ -17,7 +17,7 @@ import { useActions } from './use_actions'; describe('Transform: Transform List Actions', () => { test('useActions()', async () => { const queryClient = new QueryClient(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); const { result, waitForNextUpdate } = renderHook( diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx index b6b6636e91f38..b1d2b6dcb0d42 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx @@ -17,7 +17,7 @@ jest.mock('../../../../app_dependencies'); describe('Transform: Job List Columns', () => { test('useColumns()', async () => { const queryClient = new QueryClient(); - const wrapper: FC = ({ children }) => ( + const wrapper: FC> = ({ children }) => ( {children} ); const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, [], false), { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx index 9a98adc0f48d9..d17fbfecd87e0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/toast_with_circuit_breaker_content.tsx @@ -23,7 +23,7 @@ const hideFullErrorMessage = i18n.translate( } ); -export const ToastWithCircuitBreakerContent: FC = ({ children }) => { +export const ToastWithCircuitBreakerContent: FC> = ({ children }) => { const [showDetails, setShowDetails] = useState(false); const onToggleShowDetails = useCallback(() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx index eb51ecde8cbaa..9e03d0ae0971a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx @@ -25,7 +25,7 @@ export interface AppMockRenderer { render: UiRender; coreStart: TriggersAndActionsUiServices; queryClient: QueryClient; - AppWrapper: FC; + AppWrapper: FC>; } export const createAppMockRenderer = ( @@ -51,7 +51,7 @@ export const createAppMockRenderer = ( }, }); - const AppWrapper = React.memo(({ children }) => ( + const AppWrapper = React.memo>(({ children }) => ( diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx index c9dbe72e142e0..19c0ca1276b6b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/components/loading_issues_error.tsx @@ -8,7 +8,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiIcon } from '@elastic/eui'; -export const LoadingIssuesError: FC = ({ children }) => ( +export const LoadingIssuesError: FC> = ({ children }) => ( From c83cb883460d339837a8c8f4a82c45cc4ac96f59 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 29 Apr 2024 23:26:35 +0100 Subject: [PATCH 018/104] skip flaky suite (#182021) --- .../cypress/e2e/investigations/timelines/row_renderers.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts index 09e04c28e4975..b27ea9fcc6a81 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts @@ -27,7 +27,8 @@ import { addNameToTimelineAndSave, populateTimeline, saveTimeline } from '../../ import { hostsUrl } from '../../../urls/navigation'; -describe('Row renderers', { tags: ['@ess', '@serverless'] }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/182021 +describe.skip('Row renderers', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { deleteTimelines(); login(); From 8a9674680d1405ac03ac456c7f2e676f89c46646 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 29 Apr 2024 23:28:20 +0100 Subject: [PATCH 019/104] skip flaky suite (#174975) --- .../test/security_solution_endpoint/apps/integrations/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_endpoint/apps/integrations/index.ts b/x-pack/test/security_solution_endpoint/apps/integrations/index.ts index 1f830a06d3103..797c78a37aa1b 100644 --- a/x-pack/test/security_solution_endpoint/apps/integrations/index.ts +++ b/x-pack/test/security_solution_endpoint/apps/integrations/index.ts @@ -16,7 +16,8 @@ import { export default function (providerContext: FtrProviderContext) { const { loadTestFile, getService, getPageObjects } = providerContext; - describe('endpoint', function () { + // FLAKY: https://github.com/elastic/kibana/issues/174975 + describe.skip('endpoint', function () { const ingestManager = getService('ingestManager'); const log = getService('log'); const endpointTestResources = getService('endpointTestResources'); From d08ce905592d060a98bd488521eaceea9ff2aa47 Mon Sep 17 00:00:00 2001 From: Samiul Monir <150824886+Samiul-TheSoccerFan@users.noreply.github.com> Date: Mon, 29 Apr 2024 20:23:23 -0400 Subject: [PATCH 020/104] [Playground] Adding TECH PREVIEW badge for Playground (#182019) ## Summary - Adding badge in Playground - Enabling for Serverless ### Serverless ![serverless](https://github.com/elastic/kibana/assets/150824886/6dde57b1-dd2b-4c55-ac6f-37e55cc4a61e) ### Stack ![stack](https://github.com/elastic/kibana/assets/150824886/3fd7f81f-c324-499a-bdd5-1f0bb1eae3e1) ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- config/serverless.es.yml | 2 +- .../components/playground/playground.tsx | 27 +++++++++++++++-- .../public/chat_playground_overview.tsx | 29 +++++++++++++++---- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/config/serverless.es.yml b/config/serverless.es.yml index 1f7f200c71a13..c7d5044ac2c2c 100644 --- a/config/serverless.es.yml +++ b/config/serverless.es.yml @@ -46,4 +46,4 @@ xpack.ml.compatibleModuleType: 'search' data_visualizer.resultLinks.fileBeat.enabled: false # Search Playground -xpack.searchPlayground.ui.enabled: false +xpack.searchPlayground.ui.enabled: true diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/playground/playground.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/playground/playground.tsx index a286f865c6a1c..8667c9641a704 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/playground/playground.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/playground/playground.tsx @@ -11,8 +11,11 @@ import { useSearchParams } from 'react-router-dom-v5-compat'; import { useValues } from 'kea'; +import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + import { KibanaLogic } from '../../../shared/kibana'; import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; @@ -39,9 +42,27 @@ export const Playground: React.FC = () => { }), ]} pageHeader={{ - pageTitle: i18n.translate('xpack.enterpriseSearch.content.playground.headerTitle', { - defaultMessage: 'Playground', - }), + pageTitle: ( + + + + + + + + + ), rightSideItems: [], }} pageViewTelemetry="Playground" diff --git a/x-pack/plugins/search_playground/public/chat_playground_overview.tsx b/x-pack/plugins/search_playground/public/chat_playground_overview.tsx index 98d608565f8ca..6454266064454 100644 --- a/x-pack/plugins/search_playground/public/chat_playground_overview.tsx +++ b/x-pack/plugins/search_playground/public/chat_playground_overview.tsx @@ -7,7 +7,8 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { EuiPageTemplate } from '@elastic/eui'; +import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiPageTemplate } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; import { PlaygroundProvider } from './providers/playground_provider'; import { App } from './components/app'; @@ -23,11 +24,27 @@ export const ChatPlaygroundOverview: React.FC = () => { > + + + + + + + + + + } + data-test-subj="chat-playground-home-page" rightSideItems={[, ]} /> From 71f8e9769a8ce7e6112bae922fc72c0064722d91 Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Tue, 30 Apr 2024 05:08:55 +0200 Subject: [PATCH 021/104] [Discover] Add timeout to "View all matches" request (#181859) - Related to https://github.com/elastic/kibana/issues/181662 ## Summary This PR adds a `timeout` param so "View all matches" functionality does not create long running requests. For testing I used oblt edge cluster with `remote_cluster:logs*,kibana_sample_data_logs` as an index pattern and `css*` as a query. --- .../use_fetch_occurances_range.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/plugins/discover/public/application/main/components/no_results/no_results_suggestions/use_fetch_occurances_range.ts b/src/plugins/discover/public/application/main/components/no_results/no_results_suggestions/use_fetch_occurances_range.ts index 24c6f6e182c55..3e878735967ef 100644 --- a/src/plugins/discover/public/application/main/components/no_results/no_results_suggestions/use_fetch_occurances_range.ts +++ b/src/plugins/discover/public/application/main/components/no_results/no_results_suggestions/use_fetch_occurances_range.ts @@ -124,6 +124,7 @@ async function fetchDocumentsTimeRange({ size: 0, track_total_hits: false, body: { + timeout: '20s', query: dslQuery ?? { match_all: {} }, aggs: { earliest_timestamp: { @@ -148,6 +149,17 @@ async function fetchDocumentsTimeRange({ ) ); + if (result.rawResponse?.timed_out) { + return null; + } + + if ( + result.rawResponse?._clusters?.total !== result.rawResponse?._clusters?.successful || + result.rawResponse?._shards?.total !== result.rawResponse?._shards?.successful + ) { + return null; + } + const earliestTimestamp = ( result.rawResponse?.aggregations?.earliest_timestamp as AggregationsSingleMetricAggregateBase )?.value_as_string; From 36493be2366ec36f50be2dcae464bc738de95315 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 30 Apr 2024 08:01:42 +0200 Subject: [PATCH 022/104] [ES|QL] Enable in serverless (#180706) ## Summary Enables ES|QL in serverless. I am working on tests on a follow up PR https://github.com/elastic/kibana/pull/181570 This is going to be merged when ES is being merged https://github.com/elastic/elasticsearch-serverless/pull/1588 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- config/serverless.yml | 2 +- packages/kbn-management/settings/setting_ids/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index efe339e428392..6fbe9496f705b 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -138,7 +138,7 @@ xpack.actions.queued.max: 10000 # Disables ESQL in advanced settings (hides it from the UI) uiSettings: overrides: - discover:enableESQL: false + discover:enableESQL: true # Task Manager xpack.task_manager.allow_reading_invalid_state: false diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index bd026c15c54db..771d60fb573aa 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -73,7 +73,7 @@ export const CONTEXT_DEFAULT_SIZE_ID = 'context:defaultSize'; export const CONTEXT_STEP_ID = 'context:step'; export const CONTEXT_TIE_BREAKER_FIELDS_ID = 'context:tieBreakerFields'; export const DEFAULT_COLUMNS_ID = 'defaultColumns'; -export const DISCOVER_ENABLE_SQL_ID = 'discover:enableSql'; +export const DISCOVER_ENABLE_ESQL_ID = 'discover:enableESQL'; export const DISCOVER_MAX_DOC_FIELDS_DISPLAYED_ID = 'discover:maxDocFieldsDisplayed'; export const DISCOVER_MODIFY_COLUMNS_ON_SWITCH_ID = 'discover:modifyColumnsOnSwitch'; export const DISCOVER_ROW_HEIGHT_OPTION_ID = 'discover:rowHeightOption'; From 9edb9d5734ee6eeadd6b2d8362a063cfc8ab3c8f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 30 Apr 2024 10:29:31 +0200 Subject: [PATCH 023/104] [Discover][Obs ai assistant] Set the index pattern on the context api to generate correct ES|QL queries etc (#181001) ## Summary Sets the index pattern correctly in the obs ai assistant. The Obs ai assistant is part of Discover in serverless Oblt project and can also be set up everywhere from the Observability AI Assistant scope advanced setting. It is a very useful tool for the Discover users and for moving from KQL to ES|QL world. This is important for prompts such as: - Transform the KQL and filters to ES|QL ![meow](https://github.com/elastic/kibana/assets/17003240/e9b1be13-667a-4fdb-addb-fb77e485b99e) - More image Other interesting prompts: - Equivalent of KQL of where filters image - Explain the ES|QL query image - Run questions on your dataset and unified search bar selection image --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/discover/kibana.jsonc | 3 ++- .../main/components/layout/discover_layout.tsx | 11 +++++++++++ src/plugins/discover/public/build_services.ts | 3 +++ src/plugins/discover/public/plugin.tsx | 6 ++++++ src/plugins/discover/tsconfig.json | 3 ++- 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/plugins/discover/kibana.jsonc b/src/plugins/discover/kibana.jsonc index 17693545dd6d0..9b892ee79fe16 100644 --- a/src/plugins/discover/kibana.jsonc +++ b/src/plugins/discover/kibana.jsonc @@ -37,7 +37,8 @@ "savedObjectsTaggingOss", "lens", "noDataPage", - "globalSearch" + "globalSearch", + "observabilityAIAssistant" ], "requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedSearch", "savedObjects"], "extraPublicDirs": ["common"] diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index 344e0b36c9d0e..a104dc3c9d73b 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -71,6 +71,7 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { filterManager, history, spaces, + observabilityAIAssistant, } = useDiscoverServices(); const pageBackgroundColor = useEuiBackgroundColor('plain'); const globalQueryState = data.query.getState(); @@ -132,6 +133,16 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { sort, }); + // The assistant is getting the state from the url correctly + // expect from the index pattern where we have only the dataview id + useEffect(() => { + return observabilityAIAssistant?.service.setScreenContext({ + screenDescription: `The user is looking at the Discover view on the ${ + isPlainRecord ? 'ES|QL' : 'dataView' + } mode. The index pattern is the ${dataView.getIndexPattern()}`, + }); + }, [dataView, isPlainRecord, observabilityAIAssistant?.service]); + const onAddFilter = useCallback( (field: DataViewField | string, values: unknown, operation: '+' | '-') => { const fieldName = typeof field === 'string' ? field : field.name; diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index fc599bd59620e..7f7bcdee2154b 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -54,6 +54,7 @@ import type { LensPublicStart } from '@kbn/lens-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { ContentClient } from '@kbn/content-management-plugin/public'; +import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public'; import { memoize, noop } from 'lodash'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; import { DiscoverStartPlugins } from './plugin'; @@ -123,6 +124,7 @@ export interface DiscoverServices { uiActions: UiActionsStart; contentClient: ContentClient; noDataPage?: NoDataPagePluginStart; + observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export const buildServices = memoize( @@ -203,6 +205,7 @@ export const buildServices = memoize( uiActions: plugins.uiActions, contentClient: plugins.contentManagement.client, noDataPage: plugins.noDataPage, + observabilityAIAssistant: plugins.observabilityAIAssistant, }; } ); diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 46cbf95d299b1..902cc0a38e717 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -46,6 +46,10 @@ import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; import { TRUNCATE_MAX_HEIGHT, ENABLE_ESQL } from '@kbn/discover-utils'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; +import type { + ObservabilityAIAssistantPublicSetup, + ObservabilityAIAssistantPublicStart, +} from '@kbn/observability-ai-assistant-plugin/public'; import { PLUGIN_ID } from '../common'; import { registerFeature } from './register_feature'; import { buildServices, UrlTracker } from './build_services'; @@ -166,6 +170,7 @@ export interface DiscoverSetupPlugins { data: DataPublicPluginSetup; expressions: ExpressionsSetup; globalSearch?: GlobalSearchPluginSetup; + observabilityAIAssistant?: ObservabilityAIAssistantPublicSetup; } /** @@ -196,6 +201,7 @@ export interface DiscoverStartPlugins { lens: LensPublicStart; contentManagement: ContentManagementPublicStart; noDataPage?: NoDataPagePluginStart; + observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export type StartRenderServices = Pick; diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index b10dee36e3fb7..6b576f3a08c1a 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -83,7 +83,8 @@ "@kbn/deeplinks-analytics", "@kbn/shared-ux-markdown", "@kbn/data-view-utils", - "@kbn/presentation-publishing" + "@kbn/presentation-publishing", + "@kbn/observability-ai-assistant-plugin" ], "exclude": ["target/**/*"] } From fa5211eeffd9c083a912254df077f6165bcdc8dd Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 10:57:34 +0200 Subject: [PATCH 024/104] Add missing type defaults to RouteDependencies (#182078) ## Summary Typescript was temporarily out, so some type issues snuck in. This PR attempts to fix it, by adding missed field `enableTogglingDataRetention` on type `RouteDependencies` --------- Co-authored-by: Ignacio Rivas --- .../api/component_templates/register_privileges_route.test.ts | 2 ++ .../api/enrich_policies/register_privileges_route.test.ts | 2 ++ .../index_management/server/test/helpers/route_dependencies.ts | 1 + 3 files changed, 5 insertions(+) diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts index 3f6b1114896c6..8367010d1b741 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts @@ -49,6 +49,7 @@ describe('GET privileges', () => { isLegacyTemplatesEnabled: true, isIndexStatsEnabled: true, isDataStreamsStorageColumnEnabled: true, + enableTogglingDataRetention: true, }, indexDataEnricher: mockedIndexDataEnricher, lib: { @@ -118,6 +119,7 @@ describe('GET privileges', () => { isLegacyTemplatesEnabled: true, isIndexStatsEnabled: true, isDataStreamsStorageColumnEnabled: true, + enableTogglingDataRetention: true, }, indexDataEnricher: mockedIndexDataEnricher, lib: { diff --git a/x-pack/plugins/index_management/server/routes/api/enrich_policies/register_privileges_route.test.ts b/x-pack/plugins/index_management/server/routes/api/enrich_policies/register_privileges_route.test.ts index 6d22d93d0e1e6..9b8f461036708 100644 --- a/x-pack/plugins/index_management/server/routes/api/enrich_policies/register_privileges_route.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/enrich_policies/register_privileges_route.test.ts @@ -49,6 +49,7 @@ describe('GET privileges', () => { isLegacyTemplatesEnabled: true, isIndexStatsEnabled: true, isDataStreamsStorageColumnEnabled: true, + enableTogglingDataRetention: true, }, indexDataEnricher: mockedIndexDataEnricher, lib: { @@ -118,6 +119,7 @@ describe('GET privileges', () => { isLegacyTemplatesEnabled: true, isIndexStatsEnabled: true, isDataStreamsStorageColumnEnabled: true, + enableTogglingDataRetention: true, }, indexDataEnricher: mockedIndexDataEnricher, lib: { diff --git a/x-pack/plugins/index_management/server/test/helpers/route_dependencies.ts b/x-pack/plugins/index_management/server/test/helpers/route_dependencies.ts index 6bde838f3c212..b939f374be078 100644 --- a/x-pack/plugins/index_management/server/test/helpers/route_dependencies.ts +++ b/x-pack/plugins/index_management/server/test/helpers/route_dependencies.ts @@ -15,6 +15,7 @@ export const routeDependencies: Omit = { isLegacyTemplatesEnabled: true, isIndexStatsEnabled: true, isDataStreamsStorageColumnEnabled: true, + enableTogglingDataRetention: true, }, indexDataEnricher: new IndexDataEnricher(), lib: { From 77961a68e05398731224f79c4189c783bb2ea142 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 11:20:45 +0200 Subject: [PATCH 025/104] [BK] Migrate batch 7 (Performance) (#181133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Validation: - [x] RREs checked locally - [x] Pipelines staged - [x] kibana / single-user-performance (https://buildkite.com/elastic/kibana-migration-pipeline-staging/builds/62 ✅ ) - [x] kibana / performance-data-set-extraction (https://buildkite.com/elastic/kibana-migration-pipeline-staging/builds/60#018f0b96-7703-4e36-9924-f405073d0747 ✅ ) - [x] kibana / scalability-benchmarking (https://buildkite.com/elastic/kibana-migration-pipeline-staging/builds/68 ✅ ) - [x] kibana / apis-capacity-testing (https://buildkite.com/elastic/kibana-migration-pipeline-staging/builds/60#018f0b96-7703-4e36-9924-f405073d0747 ✅ ) - [x] 7.17 / 8.14 validation ( ⚪ not needed, no branch builds set up) Part of: https://github.com/elastic/kibana-operations/issues/79 Migrates: - kibana / single-user-performance [kibana-performance-daily.yml](https://buildkite.com/elastic/kibana-single-user-performance) - kibana / performance-data-set-extraction [kibana-performance-data-set-extraction-daily.yml](https://buildkite.com/elastic/kibana-performance-data-set-extraction) - kibana / scalability-benchmarking [scalability_testing-daily.yml](https://buildkite.com/elastic/kibana-scalability-benchmarking-1) - kibana / apis-capacity-testing [kibana-apis-capacity-testing-daily.yml](https://buildkite.com/elastic/kibana-apis-capacity-testing) chore(BK): Migrate batch 7 - performance and testing Depends on: https://elasticco.atlassian.net/browse/ENGPRD-524 --- .../kibana-apis-capacity-testing-daily.yml | 48 +++++++++++++++++++ .../kibana-performance-daily.yml | 48 +++++++++++++++++++ ...-performance-data-set-extraction-daily.yml | 48 +++++++++++++++++++ .../locations.yml | 4 ++ .../scalability_testing-daily.yml | 48 +++++++++++++++++++ .buildkite/pipelines/performance/daily.yml | 22 +++++++-- .../performance/data_set_extraction_daily.yml | 28 +++++++++-- .../api_capacity_testing_daily.yml | 16 +++++-- .buildkite/pipelines/scalability/daily.yml | 10 +++- 9 files changed, 258 insertions(+), 14 deletions(-) create mode 100644 .buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml create mode 100644 .buildkite/pipeline-resource-definitions/kibana-performance-daily.yml create mode 100644 .buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml create mode 100644 .buildkite/pipeline-resource-definitions/scalability_testing-daily.yml diff --git a/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml new file mode 100644 index 0000000000000..8a3de7a48f61a --- /dev/null +++ b/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: bk-kibana-apis-capacity-testing + description: Runs capacity tests for Kibana apis + links: + - url: 'https://buildkite.com/elastic/kibana-apis-capacity-testing' + title: Pipeline link +spec: + type: buildkite-pipeline + owner: 'group:kibana-operations' + system: buildkite + implementation: + apiVersion: buildkite.elastic.dev/v1 + kind: Pipeline + metadata: + name: kibana / apis-capacity-testing + description: Runs capacity tests for Kibana apis + spec: + env: + SLACK_NOTIFICATIONS_CHANNEL: '#kibana-performance-alerts' + BAZEL_CACHE_MODE: none + ELASTIC_SLACK_NOTIFICATIONS_ENABLED: 'true' + allow_rebuilds: true + branch_configuration: main + default_branch: main + repository: elastic/kibana + pipeline_file: .buildkite/pipelines/scalability/api_capacity_testing_daily.yml + skip_intermediate_builds: false + provider_settings: + build_branches: true + prefix_pull_request_fork_branch_names: false + skip_pull_request_builds_for_existing_commits: false + teams: + everyone: + access_level: BUILD_AND_READ + kibana-operations: + access_level: MANAGE_BUILD_AND_READ + appex-qa: + access_level: MANAGE_BUILD_AND_READ + kibana-tech-leads: + access_level: MANAGE_BUILD_AND_READ + schedules: + Capacity every 3h testing: + cronline: 0 1/3 * * * Europe/Berlin + message: Capacity every 3h testing + branch: main diff --git a/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml new file mode 100644 index 0000000000000..b02cf449d05e2 --- /dev/null +++ b/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: bk-kibana-single-user-performance + description: Runs single user performance tests for kibana + links: + - url: 'https://buildkite.com/elastic/kibana-single-user-performance' + title: Pipeline link +spec: + type: buildkite-pipeline + owner: 'group:kibana-operations' + system: buildkite + implementation: + apiVersion: buildkite.elastic.dev/v1 + kind: Pipeline + metadata: + name: kibana / single-user-performance + description: Runs single user performance tests for kibana + spec: + env: + SLACK_NOTIFICATIONS_CHANNEL: '#kibana-performance-alerts' + BAZEL_CACHE_MODE: none + ELASTIC_SLACK_NOTIFICATIONS_ENABLED: 'true' + allow_rebuilds: true + branch_configuration: main + default_branch: main + repository: elastic/kibana + pipeline_file: .buildkite/pipelines/performance/daily.yml + skip_intermediate_builds: false + provider_settings: + build_branches: true + prefix_pull_request_fork_branch_names: false + skip_pull_request_builds_for_existing_commits: false + teams: + everyone: + access_level: BUILD_AND_READ + kibana-operations: + access_level: MANAGE_BUILD_AND_READ + appex-qa: + access_level: MANAGE_BUILD_AND_READ + kibana-tech-leads: + access_level: MANAGE_BUILD_AND_READ + schedules: + Single user daily test: + cronline: 0 */3 * * * Europe/Berlin + message: Single user daily test + branch: main diff --git a/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml new file mode 100644 index 0000000000000..d4e3120d3bcb3 --- /dev/null +++ b/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: bk-kibana-performance-data-set-extraction + description: Runs single user performance tests and extract APM traces + links: + - url: 'https://buildkite.com/elastic/kibana-performance-data-set-extraction' + title: Pipeline link +spec: + type: buildkite-pipeline + owner: 'group:kibana-operations' + system: buildkite + implementation: + apiVersion: buildkite.elastic.dev/v1 + kind: Pipeline + metadata: + name: kibana / performance-data-set-extraction + description: Runs single user performance tests and extract APM traces + spec: + env: + SLACK_NOTIFICATIONS_CHANNEL: '#kibana-performance-alerts' + BAZEL_CACHE_MODE: none + ELASTIC_SLACK_NOTIFICATIONS_ENABLED: 'true' + allow_rebuilds: true + branch_configuration: main + default_branch: main + repository: elastic/kibana + pipeline_file: .buildkite/pipelines/performance/data_set_extraction_daily.yml + skip_intermediate_builds: false + provider_settings: + build_branches: true + prefix_pull_request_fork_branch_names: false + skip_pull_request_builds_for_existing_commits: false + teams: + everyone: + access_level: BUILD_AND_READ + kibana-operations: + access_level: MANAGE_BUILD_AND_READ + appex-qa: + access_level: MANAGE_BUILD_AND_READ + kibana-tech-leads: + access_level: MANAGE_BUILD_AND_READ + schedules: + Extract APM traces: + cronline: 0 3/8 * * * Europe/Berlin + message: Extract APM traces + branch: main diff --git a/.buildkite/pipeline-resource-definitions/locations.yml b/.buildkite/pipeline-resource-definitions/locations.yml index 2cc1439713e48..7e1d136589fc1 100644 --- a/.buildkite/pipeline-resource-definitions/locations.yml +++ b/.buildkite/pipeline-resource-definitions/locations.yml @@ -8,6 +8,7 @@ spec: type: url targets: - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-api-docs.yml + - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-coverage-daily.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-es-serverless-snapshots.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-es-snapshots.yml @@ -17,9 +18,12 @@ spec: - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-fleet-packages-daily.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-migration-staging.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-on-merge-unsupported-ftrs.yml + - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml + - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-purge-cloud-deployments.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-serverless-release.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/kibana-serverless-security-solution-quality-gate-api-integration.yml + - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/security-solution-ess/security-solution-ess.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/security-solution-quality-gate/kibana-serverless-security-solution-quality-gate-defend-workflows.yml - https://github.com/elastic/kibana/blob/main/.buildkite/pipeline-resource-definitions/security-solution-quality-gate/kibana-serverless-security-solution-quality-gate-detection-engine.yml diff --git a/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml b/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml new file mode 100644 index 0000000000000..939ed1af8d34f --- /dev/null +++ b/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: bk-kibana-scalability-benchmarking + description: Runs scalability tests for Kibana server + links: + - url: 'https://buildkite.com/elastic/kibana-scalability-benchmarking' + title: Pipeline link +spec: + type: buildkite-pipeline + owner: 'group:kibana-operations' + system: buildkite + implementation: + apiVersion: buildkite.elastic.dev/v1 + kind: Pipeline + metadata: + name: kibana / scalability-benchmarking + description: Runs scalability tests for Kibana server + spec: + env: + SLACK_NOTIFICATIONS_CHANNEL: '#kibana-performance-alerts' + BAZEL_CACHE_MODE: none + ELASTIC_SLACK_NOTIFICATIONS_ENABLED: 'true' + allow_rebuilds: true + branch_configuration: main + default_branch: main + repository: elastic/kibana + pipeline_file: .buildkite/pipelines/scalability/daily.yml + skip_intermediate_builds: false + provider_settings: + build_branches: true + prefix_pull_request_fork_branch_names: false + skip_pull_request_builds_for_existing_commits: false + teams: + everyone: + access_level: BUILD_AND_READ + kibana-operations: + access_level: MANAGE_BUILD_AND_READ + appex-qa: + access_level: MANAGE_BUILD_AND_READ + kibana-tech-leads: + access_level: MANAGE_BUILD_AND_READ + schedules: + Scalability daily benchmarking: + cronline: 0 6 * * * Europe/Berlin + message: Scalability daily benchmarking + branch: main diff --git a/.buildkite/pipelines/performance/daily.yml b/.buildkite/pipelines/performance/daily.yml index a58deb281d2c5..a9a350729e5c6 100644 --- a/.buildkite/pipelines/performance/daily.yml +++ b/.buildkite/pipelines/performance/daily.yml @@ -2,14 +2,20 @@ steps: - label: '👨‍🔧 Pre-Build' command: .buildkite/scripts/lifecycle/pre_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 - wait - label: '🧑‍🏭 Build Kibana Distribution and Plugins' command: .buildkite/scripts/steps/build_kibana.sh agents: - queue: c2-16 + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: c2-standard-16 key: build if: "build.env('KIBANA_BUILD_ID') == null || build.env('KIBANA_BUILD_ID') == ''" @@ -26,7 +32,12 @@ steps: - label: '📈 Report performance metrics to ci-stats' command: .buildkite/scripts/steps/functional/report_performance_metrics.sh agents: - queue: n2-2 + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + localSsds: 1 + localSsdInterface: nvme + machineType: n2-standard-2 depends_on: tests - wait: ~ @@ -35,4 +46,7 @@ steps: - label: '🦸 Post-Build' command: .buildkite/scripts/lifecycle/post_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 diff --git a/.buildkite/pipelines/performance/data_set_extraction_daily.yml b/.buildkite/pipelines/performance/data_set_extraction_daily.yml index 39ebad2757f59..34a5c680988dd 100644 --- a/.buildkite/pipelines/performance/data_set_extraction_daily.yml +++ b/.buildkite/pipelines/performance/data_set_extraction_daily.yml @@ -2,7 +2,10 @@ steps: - label: ':male-mechanic::skin-tone-2: Pre-Build' command: .buildkite/scripts/lifecycle/pre_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 timeout_in_minutes: 10 - wait @@ -10,14 +13,21 @@ steps: - label: ':building_construction: Build Kibana Distribution and Plugins' command: .buildkite/scripts/steps/build_kibana.sh agents: - queue: c2-16 + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: c2-standard-16 key: build if: "build.env('KIBANA_BUILD_ID') == null || build.env('KIBANA_BUILD_ID') == ''" - label: ':kibana: Performance Tests with Playwright config' command: .buildkite/scripts/steps/functional/performance_playwright.sh agents: - queue: n2-2-spot + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 + preemptible: true depends_on: build key: tests timeout_in_minutes: 90 @@ -31,7 +41,12 @@ steps: - label: ':ship: Single user journeys dataset extraction for scalability benchmarking' command: .buildkite/scripts/steps/functional/scalability_dataset_extraction.sh agents: - queue: n2-2 + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + localSsds: 1 + localSsdInterface: nvme + machineType: n2-standard-2 depends_on: tests - wait: ~ @@ -40,4 +55,7 @@ steps: - label: ':male_superhero::skin-tone-2: Post-Build' command: .buildkite/scripts/lifecycle/post_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 diff --git a/.buildkite/pipelines/scalability/api_capacity_testing_daily.yml b/.buildkite/pipelines/scalability/api_capacity_testing_daily.yml index 35fba7584bd4f..cc20be1f025c0 100644 --- a/.buildkite/pipelines/scalability/api_capacity_testing_daily.yml +++ b/.buildkite/pipelines/scalability/api_capacity_testing_daily.yml @@ -2,14 +2,21 @@ steps: - label: 'Pre-Build' command: .buildkite/scripts/lifecycle/pre_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 - wait - label: 'Build Kibana Distribution and Plugins' command: .buildkite/scripts/steps/build_kibana.sh agents: - queue: n2-16-spot + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-16 + preemptible: true key: build if: "build.env('KIBANA_BUILD_ID') == null || build.env('KIBANA_BUILD_ID') == ''" timeout_in_minutes: 60 @@ -35,4 +42,7 @@ steps: - label: 'Post-Build' command: .buildkite/scripts/lifecycle/post_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 diff --git a/.buildkite/pipelines/scalability/daily.yml b/.buildkite/pipelines/scalability/daily.yml index d88c6c00e7383..8499212347c56 100644 --- a/.buildkite/pipelines/scalability/daily.yml +++ b/.buildkite/pipelines/scalability/daily.yml @@ -2,7 +2,10 @@ steps: - label: ':male-mechanic::skin-tone-2: Pre-Build' command: .buildkite/scripts/lifecycle/pre_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 timeout_in_minutes: 10 - wait @@ -23,5 +26,8 @@ steps: - label: ':male_superhero::skin-tone-2: Post-Build' command: .buildkite/scripts/lifecycle/post_build.sh agents: - queue: kibana-default + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-qa + provider: gcp + machineType: n2-standard-2 timeout_in_minutes: 10 From 005f11ca8855e239432c03792208a34ac10a08d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Tue, 30 Apr 2024 11:26:58 +0200 Subject: [PATCH 026/104] [Search] Update "Connectors" search type to singular "Connector" (#182006) ## Summary Update search tag from "Connectors" to "Connector" ### Checklist Delete any items that are not applicable to this PR. - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../server/utils/connectors_search_result_provider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/utils/connectors_search_result_provider.ts b/x-pack/plugins/enterprise_search/server/utils/connectors_search_result_provider.ts index 3035a136f34de..bfb42c846b6dc 100644 --- a/x-pack/plugins/enterprise_search/server/utils/connectors_search_result_provider.ts +++ b/x-pack/plugins/enterprise_search/server/utils/connectors_search_result_provider.ts @@ -26,7 +26,7 @@ export function getConnectorsSearchResultProvider( ): GlobalSearchResultProvider { return { find: ({ term, types, tags }, { aborted$, client, maxResults }) => { - if (!client || !term || tags || (types && !types.includes('connectors'))) { + if (!client || !term || tags || (types && !types.includes('connector'))) { return from([[]]); } const getConnectorData = async (): Promise => { @@ -54,7 +54,7 @@ export function getConnectorsSearchResultProvider( }; return from(getConnectorData()).pipe(takeUntil(aborted$)); }, - getSearchableTypes: () => ['connectors'], + getSearchableTypes: () => ['connector'], id: 'enterpriseSearchConnectors', }; } From c84e7163a73527fd92d7e2da6668f7d0ab86bd15 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 11:31:13 +0200 Subject: [PATCH 027/104] Revert "[Discover][Obs ai assistant] Set the index pattern on the context api to generate correct ES|QL queries etc (#181001)" (#182088) This reverts commit 9edb9d5734ee6eeadd6b2d8362a063cfc8ab3c8f. --- src/plugins/discover/kibana.jsonc | 3 +-- .../main/components/layout/discover_layout.tsx | 11 ----------- src/plugins/discover/public/build_services.ts | 3 --- src/plugins/discover/public/plugin.tsx | 6 ------ src/plugins/discover/tsconfig.json | 3 +-- 5 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/plugins/discover/kibana.jsonc b/src/plugins/discover/kibana.jsonc index 9b892ee79fe16..17693545dd6d0 100644 --- a/src/plugins/discover/kibana.jsonc +++ b/src/plugins/discover/kibana.jsonc @@ -37,8 +37,7 @@ "savedObjectsTaggingOss", "lens", "noDataPage", - "globalSearch", - "observabilityAIAssistant" + "globalSearch" ], "requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedSearch", "savedObjects"], "extraPublicDirs": ["common"] diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index a104dc3c9d73b..344e0b36c9d0e 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -71,7 +71,6 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { filterManager, history, spaces, - observabilityAIAssistant, } = useDiscoverServices(); const pageBackgroundColor = useEuiBackgroundColor('plain'); const globalQueryState = data.query.getState(); @@ -133,16 +132,6 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { sort, }); - // The assistant is getting the state from the url correctly - // expect from the index pattern where we have only the dataview id - useEffect(() => { - return observabilityAIAssistant?.service.setScreenContext({ - screenDescription: `The user is looking at the Discover view on the ${ - isPlainRecord ? 'ES|QL' : 'dataView' - } mode. The index pattern is the ${dataView.getIndexPattern()}`, - }); - }, [dataView, isPlainRecord, observabilityAIAssistant?.service]); - const onAddFilter = useCallback( (field: DataViewField | string, values: unknown, operation: '+' | '-') => { const fieldName = typeof field === 'string' ? field : field.name; diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index 7f7bcdee2154b..fc599bd59620e 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -54,7 +54,6 @@ import type { LensPublicStart } from '@kbn/lens-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { ContentClient } from '@kbn/content-management-plugin/public'; -import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public'; import { memoize, noop } from 'lodash'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; import { DiscoverStartPlugins } from './plugin'; @@ -124,7 +123,6 @@ export interface DiscoverServices { uiActions: UiActionsStart; contentClient: ContentClient; noDataPage?: NoDataPagePluginStart; - observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export const buildServices = memoize( @@ -205,7 +203,6 @@ export const buildServices = memoize( uiActions: plugins.uiActions, contentClient: plugins.contentManagement.client, noDataPage: plugins.noDataPage, - observabilityAIAssistant: plugins.observabilityAIAssistant, }; } ); diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 902cc0a38e717..46cbf95d299b1 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -46,10 +46,6 @@ import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; import { TRUNCATE_MAX_HEIGHT, ENABLE_ESQL } from '@kbn/discover-utils'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; -import type { - ObservabilityAIAssistantPublicSetup, - ObservabilityAIAssistantPublicStart, -} from '@kbn/observability-ai-assistant-plugin/public'; import { PLUGIN_ID } from '../common'; import { registerFeature } from './register_feature'; import { buildServices, UrlTracker } from './build_services'; @@ -170,7 +166,6 @@ export interface DiscoverSetupPlugins { data: DataPublicPluginSetup; expressions: ExpressionsSetup; globalSearch?: GlobalSearchPluginSetup; - observabilityAIAssistant?: ObservabilityAIAssistantPublicSetup; } /** @@ -201,7 +196,6 @@ export interface DiscoverStartPlugins { lens: LensPublicStart; contentManagement: ContentManagementPublicStart; noDataPage?: NoDataPagePluginStart; - observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export type StartRenderServices = Pick; diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index 6b576f3a08c1a..b10dee36e3fb7 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -83,8 +83,7 @@ "@kbn/deeplinks-analytics", "@kbn/shared-ux-markdown", "@kbn/data-view-utils", - "@kbn/presentation-publishing", - "@kbn/observability-ai-assistant-plugin" + "@kbn/presentation-publishing" ], "exclude": ["target/**/*"] } From cb77c2d13eecf92b064328605a34737222fed541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:47:33 +0100 Subject: [PATCH 028/104] [Profiling] Differential views based on same data show different values (#182001) Related to https://github.com/elastic/kibana/pull/180677 closes https://github.com/elastic/kibana/issues/181886 There's still a small difference on the CO2 values, but that's due to different formats returned by ES apis: ``` TopN Functions "self_annual_co2_tons": 0.0068555964801996295 Flamegraph "AnnualCO2TonsInclusive": [ 0.0069, ``` After: Screenshot 2024-04-29 at 16 34 57 Screenshot 2024-04-29 at 16 35 03 --- .../differential_functions.cy.ts | 40 +++++++++---------- .../e2e/profiling_views/functions.cy.ts | 26 ++++++------ .../functions/differential_topn/index.tsx | 4 +- .../profiling/server/routes/functions.ts | 4 +- .../common/profiling_es_client.ts | 1 + .../server/services/functions/es_functions.ts | 3 ++ .../utils/create_profiling_es_client.ts | 2 + 7 files changed, 44 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/differential_functions.cy.ts b/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/differential_functions.cy.ts index 52b539286471b..187a9a09d49c7 100644 --- a/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/differential_functions.cy.ts +++ b/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/differential_functions.cy.ts @@ -31,9 +31,9 @@ describe('Differential Functions page', () => { cy.wait('@getTopNFunctions'); [ { id: 'overallPerformance', value: '0%' }, - { id: 'annualizedCo2', value: '79.81 lbs / 36.2 kg' }, - { id: 'annualizedCost', value: '$341.05' }, - { id: 'totalNumberOfSamples', value: '17,186' }, + { id: 'annualizedCo2', value: '74.49 lbs / 33.79 kg' }, + { id: 'annualizedCost', value: '$318.32' }, + { id: 'totalNumberOfSamples', value: '513' }, ].forEach((item) => { cy.get(`[data-test-subj="${item.id}_value"]`).contains(item.value); cy.get(`[data-test-subj="${item.id}_comparison_value"]`).should('not.exist'); @@ -50,9 +50,9 @@ describe('Differential Functions page', () => { cy.wait('@getTopNFunctions'); [ { id: 'overallPerformance', value: '0%' }, - { id: 'annualizedCo2', value: '0 lbs / 0 kg', comparisonValue: '79.81 lbs / 36.2 kg' }, - { id: 'annualizedCost', value: '$0', comparisonValue: '$341.05' }, - { id: 'totalNumberOfSamples', value: '0', comparisonValue: '515,580' }, + { id: 'annualizedCo2', value: '0 lbs / 0 kg', comparisonValue: '74.49 lbs / 33.79 kg' }, + { id: 'annualizedCost', value: '$0', comparisonValue: '$318.32' }, + { id: 'totalNumberOfSamples', value: '0', comparisonValue: '15,390' }, ].forEach((item) => { cy.get(`[data-test-subj="${item.id}_value"]`).contains(item.value); if (item.comparisonValue) { @@ -73,23 +73,23 @@ describe('Differential Functions page', () => { cy.wait('@getTopNFunctions'); cy.wait('@getTopNFunctions'); [ - { id: 'overallPerformance', value: '78.01%', icon: 'sortUp_success' }, + { id: 'overallPerformance', value: '65.89%', icon: 'sortUp_success' }, { id: 'annualizedCo2', - value: '9.81 lbs / 36.2 kg', - comparisonValue: '28.23 lbs / 12.81 kg (64.62%)', + value: '74.49 lbs / 33.79 kg', + comparisonValue: '25.41 lbs / 11.53 kg (65.89%)', icon: 'comparison_sortUp_success', }, { id: 'annualizedCost', - value: '$341.05', - comparisonValue: '$120.65 (64.62%)', + value: '$318.32', + comparisonValue: '$108.59 (65.89%)', icon: 'comparison_sortUp_success', }, { id: 'totalNumberOfSamples', - value: '17,186', - comparisonValue: '3,780 (78.01%)', + value: '513', + comparisonValue: '175 (65.89%)', icon: 'comparison_sortUp_success', }, ].forEach((item) => { @@ -113,23 +113,23 @@ describe('Differential Functions page', () => { cy.wait('@getTopNFunctions'); cy.wait('@getTopNFunctions'); [ - { id: 'overallPerformance', value: '354.66%', icon: 'sortDown_danger' }, + { id: 'overallPerformance', value: '193.14%', icon: 'sortDown_danger' }, { id: 'annualizedCo2', - value: '28.23 lbs / 12.81 kg', - comparisonValue: '79.81 lbs / 36.2 kg (182.67%)', + value: '25.41 lbs / 11.53 kg', + comparisonValue: '74.49 lbs / 33.79 kg (193.14%)', icon: 'comparison_sortDown_danger', }, { id: 'annualizedCost', - value: '$120.65', - comparisonValue: '$341.05 (182.67%)', + value: '$108.59', + comparisonValue: '$318.32 (193.14%)', icon: 'comparison_sortDown_danger', }, { id: 'totalNumberOfSamples', - value: '3,780', - comparisonValue: '17,186 (354.66%)', + value: '175', + comparisonValue: '513 (193.14%)', icon: 'comparison_sortDown_danger', }, ].forEach((item) => { diff --git a/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts b/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts index bd2822d300240..3fc0c535639ee 100644 --- a/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts +++ b/x-pack/plugins/observability_solution/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts @@ -38,8 +38,8 @@ describe('Functions page', () => { cy.get(firstRowSelector).eq(2).contains('vmlinux'); cy.get(firstRowSelector).eq(3).contains('0.16%'); cy.get(firstRowSelector).eq(4).contains('0.16%'); - cy.get(firstRowSelector).eq(5).contains('4.41 lbs / 2 kg'); - cy.get(firstRowSelector).eq(6).contains('$18.61'); + cy.get(firstRowSelector).eq(5).contains('3.97 lbs / 1.8 kg'); + cy.get(firstRowSelector).eq(6).contains('$17.37'); cy.get(firstRowSelector).eq(7).contains('28'); }); @@ -66,16 +66,16 @@ describe('Functions page', () => { { parentKey: 'impactEstimates', key: 'annualizedSelfCoreSeconds', value: '17.03 days' }, { parentKey: 'impactEstimates', key: 'co2Emission', value: '~0.00 lbs / ~0.00 kg' }, { parentKey: 'impactEstimates', key: 'selfCo2Emission', value: '~0.00 lbs / ~0.00 kg' }, - { parentKey: 'impactEstimates', key: 'annualizedCo2Emission', value: '4.41 lbs / 2 kg' }, + { parentKey: 'impactEstimates', key: 'annualizedCo2Emission', value: '3.97 lbs / 1.8 kg' }, { parentKey: 'impactEstimates', key: 'annualizedSelfCo2Emission', - value: '4.41 lbs / 2 kg', + value: '3.97 lbs / 1.8 kg', }, { parentKey: 'impactEstimates', key: 'dollarCost', value: '$~0.00' }, { parentKey: 'impactEstimates', key: 'selfDollarCost', value: '$~0.00' }, - { parentKey: 'impactEstimates', key: 'annualizedDollarCost', value: '$18.61' }, - { parentKey: 'impactEstimates', key: 'annualizedSelfDollarCost', value: '$18.61' }, + { parentKey: 'impactEstimates', key: 'annualizedDollarCost', value: '$17.37' }, + { parentKey: 'impactEstimates', key: 'annualizedSelfDollarCost', value: '$17.37' }, ].forEach(({ parentKey, key, value }) => { cy.get(`[data-test-subj="${parentKey}_${key}"]`).contains(value); }); @@ -134,7 +134,7 @@ describe('Functions page', () => { columnIndex: 5, highRank: 693, lowRank: 44, - highValue: '48.28 lbs / 21.9 kg', + highValue: '44.97 lbs / 20.4 kg', lowValue: '0 lbs / 0 kg', }, { @@ -142,8 +142,8 @@ describe('Functions page', () => { columnIndex: 6, highRank: 693, lowRank: 44, - highValue: '$206.09', - lowValue: '$0.66', + highValue: '$192.36', + lowValue: '$0.62', }, ].forEach(({ columnKey, columnIndex, highRank, highValue, lowRank, lowValue }) => { cy.get(`[data-test-subj="dataGridHeaderCell-${columnKey}"]`).click(); @@ -189,7 +189,7 @@ describe('Functions page', () => { const firstRowSelector = '[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"]'; cy.get(firstRowSelector).eq(1).contains('1'); cy.get(firstRowSelector).eq(2).contains('vmlinux'); - cy.get(firstRowSelector).eq(5).contains('4.41 lbs / 2 kg'); + cy.get(firstRowSelector).eq(5).contains('3.97 lbs / 1.8 kg'); cy.contains('Settings').click(); cy.contains('Advanced Settings'); cy.get(`[data-test-subj="management-settings-editField-${profilingCo2PerKWH}"]`) @@ -208,7 +208,7 @@ describe('Functions page', () => { }); cy.go('back'); cy.wait('@getTopNFunctions'); - cy.get(firstRowSelector).eq(5).contains('2k lbs / 908.4 kg'); + cy.get(firstRowSelector).eq(5).contains('1.87k lbs / 847.8 kg'); const firstRowSelectorActionButton = '[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"] .euiButtonIcon'; cy.get(firstRowSelectorActionButton).click(); @@ -218,12 +218,12 @@ describe('Functions page', () => { { parentKey: 'impactEstimates', key: 'annualizedCo2Emission', - value: '2k lbs / 908.4 kg', + value: '1.87k lbs / 847.8 kg', }, { parentKey: 'impactEstimates', key: 'annualizedSelfCo2Emission', - value: '2k lbs / 908.4 kg', + value: '1.87k lbs / 847.8 kg', }, ].forEach(({ parentKey, key, value }) => { cy.get(`[data-test-subj="${parentKey}_${key}"]`).contains(value); diff --git a/x-pack/plugins/observability_solution/profiling/public/views/functions/differential_topn/index.tsx b/x-pack/plugins/observability_solution/profiling/public/views/functions/differential_topn/index.tsx index 007f6a3546b7b..33acae723b821 100644 --- a/x-pack/plugins/observability_solution/profiling/public/views/functions/differential_topn/index.tsx +++ b/x-pack/plugins/observability_solution/profiling/public/views/functions/differential_topn/index.tsx @@ -173,7 +173,7 @@ export function DifferentialTopNFunctionsView() { baseValue={ state.data ? { - totalCount: state.data.TotalCount, + totalCount: state.data.selfCPU, scaleFactor: isNormalizedByTime ? baselineTime : baseline, totalAnnualCO2Kgs: state.data.totalAnnualCO2Kgs, totalAnnualCostUSD: state.data.totalAnnualCostUSD, @@ -183,7 +183,7 @@ export function DifferentialTopNFunctionsView() { comparisonValue={ comparisonState.data ? { - totalCount: comparisonState.data.TotalCount, + totalCount: comparisonState.data.selfCPU, scaleFactor: isNormalizedByTime ? comparisonTime : comparison, totalAnnualCO2Kgs: comparisonState.data.totalAnnualCO2Kgs, totalAnnualCostUSD: comparisonState.data.totalAnnualCostUSD, diff --git a/x-pack/plugins/observability_solution/profiling/server/routes/functions.ts b/x-pack/plugins/observability_solution/profiling/server/routes/functions.ts index e7dd4e7f9d908..4f30ff0c8f238 100644 --- a/x-pack/plugins/observability_solution/profiling/server/routes/functions.ts +++ b/x-pack/plugins/observability_solution/profiling/server/routes/functions.ts @@ -67,6 +67,7 @@ export function registerTopNFunctionsSearchRoute({ const useStacktracesAPI = await core.uiSettings.client.get( profilingFetchTopNFunctionsFromStacktraces ); + const totalSeconds = endSecs - startSecs; const topNFunctions = useStacktracesAPI ? await profilingDataAccess.services.fetchFunctions({ @@ -74,7 +75,7 @@ export function registerTopNFunctionsSearchRoute({ esClient, startIndex, endIndex, - totalSeconds: endSecs - startSecs, + totalSeconds, query, }) : await profilingDataAccess.services.fetchESFunctions({ @@ -82,6 +83,7 @@ export function registerTopNFunctionsSearchRoute({ esClient, query, aggregationField: 'service.name', + totalSeconds, }); return response.ok({ diff --git a/x-pack/plugins/observability_solution/profiling_data_access/common/profiling_es_client.ts b/x-pack/plugins/observability_solution/profiling_data_access/common/profiling_es_client.ts index 96cef8726cf66..a5ef490d720d1 100644 --- a/x-pack/plugins/observability_solution/profiling_data_access/common/profiling_es_client.ts +++ b/x-pack/plugins/observability_solution/profiling_data_access/common/profiling_es_client.ts @@ -65,5 +65,6 @@ export interface ProfilingESClient { awsCostDiscountRate?: number; azureCostDiscountRate?: number; costPervCPUPerHour?: number; + durationSeconds: number; }): Promise; } diff --git a/x-pack/plugins/observability_solution/profiling_data_access/server/services/functions/es_functions.ts b/x-pack/plugins/observability_solution/profiling_data_access/server/services/functions/es_functions.ts index 3296ab2141d1c..2692af8f2fdc0 100644 --- a/x-pack/plugins/observability_solution/profiling_data_access/server/services/functions/es_functions.ts +++ b/x-pack/plugins/observability_solution/profiling_data_access/server/services/functions/es_functions.ts @@ -33,6 +33,7 @@ export interface FetchFunctionsParams { query: QueryDslQueryContainer; aggregationField?: AggregationField; limit?: number; + totalSeconds: number; } const targetSampleSize = 20000; // minimum number of samples to get statistically sound results @@ -46,6 +47,7 @@ export function createFetchESFunctions({ createProfilingEsClient }: RegisterServ query, aggregationField, limit, + totalSeconds, }: FetchFunctionsParams) => { const [ co2PerKWH, @@ -82,6 +84,7 @@ export function createFetchESFunctions({ createProfilingEsClient }: RegisterServ awsCostDiscountRate: percentToFactor(awsCostDiscountRate), costPervCPUPerHour, azureCostDiscountRate: percentToFactor(azureCostDiscountRate), + durationSeconds: totalSeconds, }); return transformToKibanaTopNFunction(esTopNFunctions); diff --git a/x-pack/plugins/observability_solution/profiling_data_access/server/utils/create_profiling_es_client.ts b/x-pack/plugins/observability_solution/profiling_data_access/server/utils/create_profiling_es_client.ts index ab7483a99916f..e80a36087b533 100644 --- a/x-pack/plugins/observability_solution/profiling_data_access/server/utils/create_profiling_es_client.ts +++ b/x-pack/plugins/observability_solution/profiling_data_access/server/utils/create_profiling_es_client.ts @@ -165,6 +165,7 @@ export function createProfilingEsClient({ azureCostDiscountRate, sampleSize, limit, + durationSeconds, }) { const controller = new AbortController(); @@ -187,6 +188,7 @@ export function createProfilingEsClient({ aws_cost_factor: awsCostDiscountRate, cost_per_core_hour: costPervCPUPerHour, azure_cost_factor: azureCostDiscountRate, + requested_duration: durationSeconds, }, }, { From 370a7f5ec625fec1d082b331bfe431b68ed63688 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 12:09:02 +0200 Subject: [PATCH 029/104] [Fix] Add missing totalSeconds field (#182093) ## Summary The PR https://github.com/elastic/kibana/pull/182001 was verified at a point where typechecking was missing for a bit, this allowed a missing field to slip in. This PR tries to fix it. --- .../observability_solution/profiling/server/routes/apm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts index f77d121a699d2..e5119c17ee5da 100644 --- a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts +++ b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts @@ -83,6 +83,7 @@ export function registerTopNFunctionsAPMTransactionsRoute({ indices: transactionIndices.split(','), stacktraceIdsField: 'transaction.profiler_stack_trace_ids', limit: 1000, + totalSeconds: endSecs - startSecs, }); const apmFunction = apmFunctions.TopN.find( (topNFunction) => topNFunction.Frame.FunctionName === functionName From c27c31edefb7d3039514857a892debb37dd1632e Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 30 Apr 2024 13:29:43 +0200 Subject: [PATCH 030/104] [BK] Adjust settings to pre-migration state (#182100) ## Summary As usual, the diff through the migration revealed some drifting between our assumed defaults and the defaults on the new infra. This PR re-adjusts the settings to how it was before the migration. --- .../kibana-apis-capacity-testing-daily.yml | 5 +++-- .../kibana-performance-daily.yml | 6 ++++-- .../kibana-performance-data-set-extraction-daily.yml | 5 +++-- .../scalability_testing-daily.yml | 5 +++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml index 8a3de7a48f61a..c52e6203485f4 100644 --- a/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml +++ b/.buildkite/pipeline-resource-definitions/kibana-apis-capacity-testing-daily.yml @@ -29,9 +29,10 @@ spec: pipeline_file: .buildkite/pipelines/scalability/api_capacity_testing_daily.yml skip_intermediate_builds: false provider_settings: + trigger_mode: none build_branches: true - prefix_pull_request_fork_branch_names: false - skip_pull_request_builds_for_existing_commits: false + prefix_pull_request_fork_branch_names: true + skip_pull_request_builds_for_existing_commits: true teams: everyone: access_level: BUILD_AND_READ diff --git a/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml index b02cf449d05e2..9ed561c9cfdbe 100644 --- a/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml +++ b/.buildkite/pipeline-resource-definitions/kibana-performance-daily.yml @@ -29,9 +29,11 @@ spec: pipeline_file: .buildkite/pipelines/performance/daily.yml skip_intermediate_builds: false provider_settings: + trigger_mode: none build_branches: true - prefix_pull_request_fork_branch_names: false - skip_pull_request_builds_for_existing_commits: false + prefix_pull_request_fork_branch_names: true + publish_commit_status: false + skip_pull_request_builds_for_existing_commits: true teams: everyone: access_level: BUILD_AND_READ diff --git a/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml index d4e3120d3bcb3..aa38564fd963b 100644 --- a/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml +++ b/.buildkite/pipeline-resource-definitions/kibana-performance-data-set-extraction-daily.yml @@ -29,9 +29,10 @@ spec: pipeline_file: .buildkite/pipelines/performance/data_set_extraction_daily.yml skip_intermediate_builds: false provider_settings: + trigger_mode: none build_branches: true - prefix_pull_request_fork_branch_names: false - skip_pull_request_builds_for_existing_commits: false + prefix_pull_request_fork_branch_names: true + skip_pull_request_builds_for_existing_commits: true teams: everyone: access_level: BUILD_AND_READ diff --git a/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml b/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml index 939ed1af8d34f..06f2f2dd6634b 100644 --- a/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml +++ b/.buildkite/pipeline-resource-definitions/scalability_testing-daily.yml @@ -29,9 +29,10 @@ spec: pipeline_file: .buildkite/pipelines/scalability/daily.yml skip_intermediate_builds: false provider_settings: + trigger_mode: none build_branches: true - prefix_pull_request_fork_branch_names: false - skip_pull_request_builds_for_existing_commits: false + prefix_pull_request_fork_branch_names: true + skip_pull_request_builds_for_existing_commits: true teams: everyone: access_level: BUILD_AND_READ From e01d80066c9e6ab0967ea46a62407dce39c97280 Mon Sep 17 00:00:00 2001 From: Tiago Vila Verde Date: Tue, 30 Apr 2024 14:03:59 +0200 Subject: [PATCH 031/104] [Security Solution][Entity Analytics] Show missing risk score privileges in entity risk tabs (#180954) ## Summary This PR adds a check against the risk scoring privileges and shows the appropriate message in case they are missing. Previously, in the entity pages, if a user did not have the correct privileges, clicking on the risk tab would show a message to "Enable risk scoring". This was incorrect as the risk engine could be enabled but the user might not have the permissions to view risk scores. Previously, in **Hosts/Users page -> Host risk / User risk tab** ![image](https://github.com/elastic/kibana/assets/2423976/0d3f8073-0e5b-4e71-91b0-7d8e3fd5357c) Now: ![Screenshot 2024-04-16 at 17 41 34](https://github.com/elastic/kibana/assets/2423976/304e8af9-54af-4acf-9037-58316734bd15) ## How to test 1. Create a role which has access to all security related indices and Security Permissions. 2. Ensure that the user does not have permissions to view the `.risk-score*` index 3. Create a new user with said role from step 1 4. Login with that user and navigate to **Hosts/Users page -> Host risk / User risk tab** --- .../entity_analytics_risk_score/index.tsx | 14 +++++++++- .../risk_details_tab_body/index.tsx | 14 +++++++++- .../risk_engine_privileges_callout.tsx | 8 ++++-- .../components/user_risk_score_tab_body.tsx | 27 ++++++++++++++----- .../navigation/host_risk_score_tab_body.tsx | 11 ++++++++ .../public/explore/users/pages/users_tabs.tsx | 1 - 6 files changed, 64 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx index 0b7cc0333dbe6..71ab20090ff01 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { HostPanelKey } from '../../../flyout/entity_details/host_right'; @@ -36,6 +36,8 @@ import { useGlobalFilterQuery } from '../../../common/hooks/use_global_filter_qu import { useRiskScoreKpi } from '../../api/hooks/use_risk_score_kpi'; import { useRiskScore } from '../../api/hooks/use_risk_score'; import { UserPanelKey } from '../../../flyout/entity_details/user_right'; +import { RiskEnginePrivilegesCallOut } from '../risk_engine_privileges_callout'; +import { useMissingRiskEnginePrivileges } from '../../hooks/use_missing_risk_engine_privileges'; export const ENTITY_RISK_SCORE_TABLE_ID = 'entity-risk-score-table'; @@ -158,6 +160,8 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc const refreshPage = useRefetchQueries(); + const privileges = useMissingRiskEnginePrivileges(); + if (!isAuthorized) { return null; } @@ -167,6 +171,14 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc isDeprecated: isDeprecated && !isTableLoading, }; + if (!privileges.isLoading && !privileges.hasAllRequiredPrivileges) { + return ( + + + + ); + } + if (status.isDisabled || status.isDeprecated) { return ( theme.eui.euiSizeL}; @@ -126,6 +128,16 @@ const RiskDetailsTabBodyComponent: React.FC< [setOverTimeToggleStatus] ); + const privileges = useMissingRiskEnginePrivileges(); + + if (!privileges.isLoading && !privileges.hasAllRequiredPrivileges) { + return ( + + + + ); + } + const status = { isDisabled: !isModuleEnabled && !loading, isDeprecated: isDeprecated && !loading, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_engine_privileges_callout/risk_engine_privileges_callout.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_engine_privileges_callout/risk_engine_privileges_callout.tsx index b2b4e0def3f54..d97da719eaa95 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_engine_privileges_callout/risk_engine_privileges_callout.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_engine_privileges_callout/risk_engine_privileges_callout.tsx @@ -6,8 +6,9 @@ */ import React from 'react'; +import { EuiSpacer } from '@elastic/eui'; import type { CallOutMessage } from '../../../common/components/callouts'; -import { CallOutSwitcher } from '../../../common/components/callouts'; +import { CallOut } from '../../../common/components/callouts'; import { MissingPrivilegesCallOutBody, MISSING_PRIVILEGES_CALLOUT_TITLE } from './translations'; import type { RiskEngineMissingPrivilegesResponse } from '../../hooks/use_missing_risk_engine_privileges'; @@ -25,6 +26,9 @@ export const RiskEnginePrivilegesCallOut: React.FC<{ }; return ( - message && + <> + + + ); }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx index c216d3786434e..3d0b6bf2e334f 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx @@ -8,6 +8,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import { noop } from 'lodash/fp'; +import { EuiPanel } from '@elastic/eui'; import { useRiskScoreKpi } from '../api/hooks/use_risk_score_kpi'; import { useRiskScore } from '../api/hooks/use_risk_score'; import { UserRiskScoreQueryId } from '../common/utils'; @@ -23,6 +24,8 @@ import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../common/search_st import { RiskScoresNoDataDetected } from './risk_score_onboarding/risk_score_no_data_detected'; import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; import { RiskScoreUpdatePanel } from './risk_score_update_panel'; +import { useMissingRiskEnginePrivileges } from '../hooks/use_missing_risk_engine_privileges'; +import { RiskEnginePrivilegesCallOut } from './risk_engine_privileges_callout'; const UserRiskScoreTableManage = manageQuery(UserRiskScoreTable); @@ -63,6 +66,8 @@ export const UserRiskScoreQueryTabBody = ({ const timerange = useMemo(() => ({ from, to }), [from, to]); + const privileges = useMissingRiskEnginePrivileges(); + const { data, inspect, @@ -92,14 +97,24 @@ export const UserRiskScoreQueryTabBody = ({ isDeprecated: isDeprecated && !loading, }; + if (!privileges.isLoading && !privileges.hasAllRequiredPrivileges) { + return ( + + + + ); + } + if (status.isDisabled || status.isDeprecated) { return ( - + + + ); } diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx index c9ab211c8dc07..28f0a8dbed776 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx @@ -8,6 +8,8 @@ import React, { useEffect, useMemo, useState } from 'react'; import { EuiPanel } from '@elastic/eui'; import { noop } from 'lodash/fp'; +import { RiskEnginePrivilegesCallOut } from '../../../../entity_analytics/components/risk_engine_privileges_callout'; +import { useMissingRiskEnginePrivileges } from '../../../../entity_analytics/hooks/use_missing_risk_engine_privileges'; import { HostRiskScoreQueryId } from '../../../../entity_analytics/common/utils'; import { useRiskScoreKpi } from '../../../../entity_analytics/api/hooks/use_risk_score_kpi'; import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; @@ -64,6 +66,7 @@ export const HostRiskScoreQueryTabBody = ({ }, [toggleStatus]); const timerange = useMemo(() => ({ from, to }), [from, to]); + const privileges = useMissingRiskEnginePrivileges(); const { data, inspect, @@ -93,6 +96,14 @@ export const HostRiskScoreQueryTabBody = ({ isDeprecated: isDeprecated && !loading, }; + if (!privileges.isLoading && !privileges.hasAllRequiredPrivileges) { + return ( + + + + ); + } + if (status.isDisabled || status.isDeprecated) { return ( diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx index bc6dd85e21e25..dc5f9ae234297 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx @@ -32,7 +32,6 @@ export const UsersTabs = memo( startDate: from, type, }; - return ( From 8a1d2950fa16f8cb50a21cb793640a290b54032c Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Tue, 30 Apr 2024 08:11:43 -0400 Subject: [PATCH 032/104] [Security Solution] [Alerts Table] [RAC] Prevent duplicate items being added by bulk actions select all (#182007) ## Summary Related issue: #181972 When the useBulkActions hook in the alerts table is used with the optionally defined at registration time hook useBulkActionsConfig, and that hook returns a stable array, the hook calls a function that mutates this array directly, which causes duplicate items to appear in the alert context menu. This is due to the useBulkActions hook using the bulk actions state via context, and so runs every time a user selects a row/all rows. Doing this via filter might not be the most performant way, but in order to have everything referentially stable, I think the arguments to useBulkActions/useBulkUntrackActions should be changed a bit, but that can be a discussion for another time. The test case added below will currently fail on main/8.14. Before: ![bulk_actions_with_dupe](https://github.com/elastic/kibana/assets/56408403/7f730bb9-fcb2-4a8e-93f8-3e08523e3a34) After: ![bulk_actions_no_dupe](https://github.com/elastic/kibana/assets/56408403/01f76c6b-59fb-459f-8950-1fc1fe8dfe12) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../hooks/use_bulk_actions.test.tsx | 41 +++++++++++++ .../alerts_table/hooks/use_bulk_actions.ts | 58 +++++++++++-------- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx index 84b9180733e83..042eeab219633 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx @@ -10,6 +10,7 @@ import { useBulkActions, useBulkAddToCaseActions, useBulkUntrackActions } from ' import { AppMockRenderer, createAppMockRenderer } from '../../test_utils'; import { createCasesServiceMock } from '../index.mock'; import { AlertsTableQueryContext } from '../contexts/alerts_table_context'; +import { BulkActionsVerbs } from '../../../../types'; jest.mock('./apis/bulk_get_cases'); jest.mock('../../../../common/lib/kibana'); @@ -422,5 +423,45 @@ describe('bulk action hooks', () => { ] `); }); + + it('should not append duplicate items on rerender', async () => { + const onClick = () => {}; + const items = [ + { + label: 'test', + key: 'test', + 'data-test-subj': 'test', + disableOnQuery: true, + disabledLabel: 'test', + onClick, + }, + ]; + const customBulkActionConfig = [ + { + id: 0, + items, + }, + ]; + const useBulkActionsConfig = () => customBulkActionConfig; + const { result, rerender } = renderHook( + () => useBulkActions({ alerts: [], query: {}, casesConfig, refresh, useBulkActionsConfig }), + { + wrapper: appMockRender.AppWrapper, + } + ); + const initialBulkActions = result.current.bulkActions[0].items + ? [...result.current.bulkActions[0].items] + : []; + result.current.updateBulkActionsState({ action: BulkActionsVerbs.selectCurrentPage }); + rerender(); + result.current.updateBulkActionsState({ action: BulkActionsVerbs.clear }); + rerender(); + result.current.updateBulkActionsState({ action: BulkActionsVerbs.selectCurrentPage }); + rerender(); + result.current.updateBulkActionsState({ action: BulkActionsVerbs.selectAll }); + rerender(); + const newBulkActions = result.current.bulkActions[0].items; + expect(initialBulkActions).toEqual(newBulkActions); + }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts index 3bc36d1bdd049..17c1b5be3c7ef 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts @@ -16,6 +16,7 @@ import { BulkActionsPanelConfig, BulkActionsState, BulkActionsVerbs, + BulkActionsReducerAction, UseBulkActionsRegistry, } from '../../../../types'; import { @@ -50,6 +51,7 @@ export interface UseBulkActions { bulkActions: BulkActionsPanelConfig[]; setIsBulkActionsLoading: (isLoading: boolean) => void; clearSelection: () => void; + updateBulkActionsState: React.Dispatch; } type UseBulkAddToCaseActionsProps = Pick & @@ -90,7 +92,9 @@ const addItemsToInitialPanel = ({ }) => { if (panels.length > 0) { if (panels[0].items) { - panels[0].items.push(...items); + panels[0].items = [...panels[0].items, ...items].filter( + (item, index, self) => index === self.findIndex((newItem) => newItem.key === item.key) + ); } return panels; } else { @@ -205,6 +209,33 @@ export const useBulkUntrackActions = ({ const hasUptimePermission = application?.capabilities.uptime?.show; const hasSloPermission = application?.capabilities.slo?.show; const hasObservabilityPermission = application?.capabilities.observability?.show; + const onClick = useCallback( + async (alerts?: TimelineItem[]) => { + if (!alerts) return; + const alertUuids = alerts.map((alert) => alert._id); + const indices = alerts.map((alert) => alert._index ?? ''); + try { + setIsBulkActionsLoading(true); + if (isAllSelected) { + await untrackAlertsByQuery({ query, featureIds }); + } else { + await untrackAlerts({ indices, alertUuids }); + } + onSuccess(); + } finally { + setIsBulkActionsLoading(false); + } + }, + [ + query, + featureIds, + isAllSelected, + onSuccess, + setIsBulkActionsLoading, + untrackAlerts, + untrackAlertsByQuery, + ] + ); return useMemo(() => { // Check if at least one Observability feature is enabled @@ -225,28 +256,10 @@ export const useBulkUntrackActions = ({ disableOnQuery: false, disabledLabel: MARK_AS_UNTRACKED, 'data-test-subj': 'mark-as-untracked', - onClick: async (alerts?: TimelineItem[]) => { - if (!alerts) return; - const alertUuids = alerts.map((alert) => alert._id); - const indices = alerts.map((alert) => alert._index ?? ''); - try { - setIsBulkActionsLoading(true); - if (isAllSelected) { - await untrackAlertsByQuery({ query, featureIds }); - } else { - await untrackAlerts({ indices, alertUuids }); - } - onSuccess(); - } finally { - setIsBulkActionsLoading(false); - } - }, + onClick, }, ]; }, [ - onSuccess, - setIsBulkActionsLoading, - untrackAlerts, application?.capabilities, hasApmPermission, hasInfrastructurePermission, @@ -254,10 +267,7 @@ export const useBulkUntrackActions = ({ hasUptimePermission, hasSloPermission, hasObservabilityPermission, - featureIds, - query, - isAllSelected, - untrackAlertsByQuery, + onClick, ]); }; From 6eba59575e877b6e099426615809e8ac3bc95908 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Tue, 30 Apr 2024 14:14:52 +0200 Subject: [PATCH 033/104] [Obs AI Assistant] Refactor ObservabilityAIAssistantClient (#181255) Refactors the Observability AI Assistant server-side client. Instead of using a mix of promises and Observables, we know use Observables where possible. This leads to more readable code, and makes things like error handling and logging easier. This refactor purposely leaves the existing tests in place as much as possible. The functionality has however been broken into separate functions so we should be able to break up the existing tests into smaller pieces. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/conversation_complete.ts | 6 +- .../utils/create_function_request_message.ts | 3 +- .../utils/create_function_response_error.ts | 4 +- .../utils/emit_with_concatenated_message.ts | 26 +- .../utils/without_token_count_events.ts | 23 + .../public/mock.tsx | 2 +- .../public/service/complete.test.ts | 1 + .../public/service/create_chat_service.ts | 9 +- .../public/storybook_mock.tsx | 2 +- .../server/functions/context.ts | 24 +- .../get_relevant_field_names.ts | 19 +- .../functions/get_dataset_info/index.ts | 16 +- .../server/routes/chat/route.ts | 74 +- .../chat_function_client/index.test.ts | 2 - .../service/chat_function_client/index.ts | 7 +- .../bedrock/process_bedrock_stream.test.ts | 12 +- .../fail_on_non_existing_function_call.ts | 47 +- .../server/service/client/adapters/types.ts | 9 +- .../get_context_function_request_if_needed.ts | 35 + .../server/service/client/index.test.ts | 112 +- .../server/service/client/index.ts | 995 ++++++------------ .../client/operators/continue_conversation.ts | 294 ++++++ .../server/service/client/operators/debug.ts | 21 + .../client/operators/extract_messages.ts | 24 + .../client/operators/extract_token_count.ts | 36 + .../client/operators/get_generated_title.ts | 105 ++ .../operators/hide_token_count_events.ts | 38 + .../operators/instrument_and_count_tokens.ts | 71 ++ .../server/service/types.ts | 28 +- .../catch_function_limit_exceeded_error.ts | 7 +- .../service/util/observable_into_stream.ts | 3 +- .../service/util/reject_token_count_events.ts | 26 - .../service/util/with_assistant_span.ts | 25 + .../observability_ai_assistant/tsconfig.json | 1 + .../server/functions/query/index.ts | 4 +- .../server/functions/visualize_esql.ts | 35 +- .../tests/chat/chat.spec.ts | 5 +- 37 files changed, 1271 insertions(+), 880 deletions(-) create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/without_token_count_events.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/debug.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_messages.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_token_count.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/hide_token_count_events.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/instrument_and_count_tokens.ts delete mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/reject_token_count_events.ts create mode 100644 x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/with_assistant_span.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/conversation_complete.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/conversation_complete.ts index eed16e9c8ddb4..cc0a487331e61 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/conversation_complete.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/conversation_complete.ts @@ -103,13 +103,17 @@ export type StreamingChatResponseEvent = | ConversationCreateEvent | ConversationUpdateEvent | MessageAddEvent - | ChatCompletionErrorEvent; + | ChatCompletionErrorEvent + | TokenCountEvent; export type StreamingChatResponseEventWithoutError = Exclude< StreamingChatResponseEvent, ChatCompletionErrorEvent >; +export type ChatEvent = ChatCompletionChunkEvent | TokenCountEvent; +export type MessageOrChatEvent = ChatEvent | MessageAddEvent; + export enum ChatCompletionErrorCode { InternalError = 'internalError', NotFoundError = 'notFoundError', diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_request_message.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_request_message.ts index 45399ea651bb3..01a4a5c12537b 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_request_message.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_request_message.ts @@ -14,7 +14,7 @@ export function createFunctionRequestMessage({ args, }: { name: string; - args: unknown; + args?: Record; }): MessageAddEvent { return { id: v4(), @@ -28,6 +28,7 @@ export function createFunctionRequestMessage({ trigger: MessageRole.Assistant as const, }, role: MessageRole.Assistant, + content: '', }, }, }; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_response_error.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_response_error.ts index 79f6e5d4ff6df..bfb4021894273 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_response_error.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/create_function_response_error.ts @@ -24,9 +24,11 @@ export function createFunctionResponseError({ name: error.name, message: error.message, cause: error.cause, - stack: error.stack, }, message: message || error.message, }, + data: { + stack: error.stack, + }, }); } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/emit_with_concatenated_message.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/emit_with_concatenated_message.ts index af283b78698f1..47370cc48cf00 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/emit_with_concatenated_message.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/emit_with_concatenated_message.ts @@ -5,9 +5,20 @@ * 2.0. */ -import { concat, from, last, mergeMap, Observable, shareReplay, withLatestFrom } from 'rxjs'; +import { + concat, + from, + last, + mergeMap, + Observable, + OperatorFunction, + shareReplay, + withLatestFrom, +} from 'rxjs'; +import { withoutTokenCountEvents } from './without_token_count_events'; import { ChatCompletionChunkEvent, + ChatEvent, MessageAddEvent, StreamingChatResponseEventType, } from '../conversation_complete'; @@ -40,20 +51,21 @@ function mergeWithEditedMessage( ); } -export function emitWithConcatenatedMessage( +export function emitWithConcatenatedMessage( callback?: ConcatenateMessageCallback -): ( - source$: Observable -) => Observable { - return (source$: Observable) => { +): OperatorFunction { + return (source$) => { const shared = source$.pipe(shareReplay()); + const withoutTokenCount$ = shared.pipe(withoutTokenCountEvents()); + const response$ = concat( shared, shared.pipe( + withoutTokenCountEvents(), concatenateChatCompletionChunks(), last(), - withLatestFrom(source$), + withLatestFrom(withoutTokenCount$), mergeMap(([message, chunkEvent]) => { return mergeWithEditedMessage(message, chunkEvent, callback); }) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/without_token_count_events.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/without_token_count_events.ts new file mode 100644 index 0000000000000..137b1140fbdcd --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/without_token_count_events.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { filter, OperatorFunction } from 'rxjs'; +import { + StreamingChatResponseEvent, + StreamingChatResponseEventType, + TokenCountEvent, +} from '../conversation_complete'; + +export function withoutTokenCountEvents(): OperatorFunction< + T, + Exclude +> { + return filter( + (event): event is Exclude => + event.type !== StreamingChatResponseEventType.TokenCount + ); +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx index 28b05433b2e1e..4775ad1b551b1 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx @@ -38,7 +38,7 @@ export const mockChatService: ObservabilityAIAssistantChatService = { '@timestamp': new Date().toISOString(), message: { role: MessageRole.System, - content: '', + content: 'System', }, }), }; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts index a0b7b8fe1447e..f02471e8090d6 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts @@ -284,6 +284,7 @@ describe('complete', () => { '@timestamp': expect.any(String), message: { content: expect.any(String), + data: expect.any(String), name: 'my_action', role: MessageRole.User, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts index 4995aa1b584ba..c0b897a134dd5 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts @@ -28,7 +28,6 @@ import { StreamingChatResponseEventType, type StreamingChatResponseEventWithoutError, type StreamingChatResponseEvent, - TokenCountEvent, } from '../../common/conversation_complete'; import { FunctionRegistry, @@ -163,13 +162,7 @@ export async function createChatService({ const subscription = toObservable(response) .pipe( - map( - (line) => - JSON.parse(line) as - | StreamingChatResponseEvent - | BufferFlushEvent - | TokenCountEvent - ), + map((line) => JSON.parse(line) as StreamingChatResponseEvent | BufferFlushEvent), filter( (line): line is StreamingChatResponseEvent => line.type !== StreamingChatResponseEventType.BufferFlush && diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/storybook_mock.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant/public/storybook_mock.tsx index 1d9d79838bd3a..6cad5a52ed2f8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/storybook_mock.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/storybook_mock.tsx @@ -33,7 +33,7 @@ export const createStorybookChatService = (): ObservabilityAIAssistantChatServic '@timestamp': new Date().toISOString(), message: { role: MessageRole.System, - content: '', + content: 'System', }, }), }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts index 7c785392dfaf4..a64e63ad49c4c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts @@ -21,7 +21,7 @@ import { concatenateChatCompletionChunks } from '../../common/utils/concatenate_ import { createFunctionResponseMessage } from '../../common/utils/create_function_response_message'; import { RecallRanking, RecallRankingEventType } from '../analytics/recall_ranking'; import type { ObservabilityAIAssistantClient } from '../service/client'; -import { ChatFn } from '../service/types'; +import { FunctionCallChatFunction } from '../service/types'; import { parseSuggestionScores } from './parse_suggestion_scores'; const MAX_TOKEN_COUNT_FOR_DATA_ON_SCREEN = 1000; @@ -61,7 +61,7 @@ export function registerContextFunction({ required: ['queries', 'categories'], } as const, }, - async ({ arguments: args, messages, connectorId, screenContexts, chat }, signal) => { + async ({ arguments: args, messages, screenContexts, chat }, signal) => { const { analytics } = (await resources.context.core).coreStart; const { queries, categories } = args; @@ -118,7 +118,6 @@ export function registerContextFunction({ queries: queriesOrUserPrompt, messages, chat, - connectorId, signal, logger: resources.logger, }); @@ -209,15 +208,13 @@ async function scoreSuggestions({ messages, queries, chat, - connectorId, signal, logger, }: { suggestions: Awaited>; messages: Message[]; queries: string[]; - chat: ChatFn; - connectorId: string; + chat: FunctionCallChatFunction; signal: AbortSignal; logger: Logger; }) { @@ -274,15 +271,12 @@ async function scoreSuggestions({ }; const response = await lastValueFrom( - ( - await chat('score_suggestions', { - connectorId, - messages: [...messages.slice(0, -2), newUserMessage], - functions: [scoreFunction], - functionCall: 'score', - signal, - }) - ).pipe(concatenateChatCompletionChunks()) + chat('score_suggestions', { + messages: [...messages.slice(0, -2), newUserMessage], + functions: [scoreFunction], + functionCall: 'score', + signal, + }).pipe(concatenateChatCompletionChunks()) ); const scoreFunctionRequest = decodeOrThrow(scoreFunctionRequestRt)(response); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/get_relevant_field_names.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/get_relevant_field_names.ts index 9fc0ad4056870..543641098836f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/get_relevant_field_names.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/get_relevant_field_names.ts @@ -5,13 +5,13 @@ * 2.0. */ import datemath from '@elastic/datemath'; -import type { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { castArray, chunk, groupBy, uniq } from 'lodash'; -import { lastValueFrom, Observable } from 'rxjs'; -import type { ObservabilityAIAssistantClient } from '../../service/client'; -import { type ChatCompletionChunkEvent, type Message, MessageRole } from '../../../common'; +import { lastValueFrom } from 'rxjs'; +import { MessageRole, type Message } from '../../../common'; import { concatenateChatCompletionChunks } from '../../../common/utils/concatenate_chat_completion_chunks'; +import { FunctionCallChatFunction } from '../../service/types'; export async function getRelevantFieldNames({ index, @@ -22,6 +22,7 @@ export async function getRelevantFieldNames({ savedObjectsClient, chat, messages, + signal, }: { index: string | string[]; start?: string; @@ -30,13 +31,8 @@ export async function getRelevantFieldNames({ esClient: ElasticsearchClient; savedObjectsClient: SavedObjectsClientContract; messages: Message[]; - chat: ( - name: string, - {}: Pick< - Parameters[1], - 'functionCall' | 'functions' | 'messages' - > - ) => Promise>; + chat: FunctionCallChatFunction; + signal: AbortSignal; }): Promise<{ fields: string[] }> { const dataViewsService = await dataViews.dataViewsServiceFactory(savedObjectsClient, esClient); @@ -79,6 +75,7 @@ export async function getRelevantFieldNames({ chunk(fieldNames, 500).map(async (fieldsInChunk) => { const chunkResponse$ = ( await chat('get_relevent_dataset_names', { + signal, messages: [ { '@timestamp': new Date().toISOString(), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts index 1554df10175a2..e5b4e21195003 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts @@ -37,7 +37,7 @@ export function registerGetDatasetInfoFunction({ required: ['index'], } as const, }, - async ({ arguments: { index }, messages, connectorId, chat }, signal) => { + async ({ arguments: { index }, messages, chat }, signal) => { const coreContext = await resources.context.core; const esClient = coreContext.elasticsearch.client.asCurrentUser; @@ -83,18 +83,8 @@ export function registerGetDatasetInfoFunction({ esClient, dataViews: await resources.plugins.dataViews.start(), savedObjectsClient, - chat: ( - operationName, - { messages: nextMessages, functionCall, functions: nextFunctions } - ) => { - return chat(operationName, { - messages: nextMessages, - functionCall, - functions: nextFunctions, - connectorId, - signal, - }); - }, + signal, + chat, }); return { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts index ae96e633b3278..f5e9ca339e9e8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts @@ -8,12 +8,15 @@ import { notImplemented } from '@hapi/boom'; import { toBooleanRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; import { Readable } from 'stream'; +import type { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server'; +import { KibanaRequest } from '@kbn/core/server'; import { aiAssistantSimulatedFunctionCalling } from '../..'; import { flushBuffer } from '../../service/util/flush_buffer'; import { observableIntoStream } from '../../service/util/observable_into_stream'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; import { screenContextRt, messageRt, functionRt } from '../runtime_types'; import { ObservabilityAIAssistantRouteHandlerResources } from '../types'; +import { withAssistantSpan } from '../../service/util/with_assistant_span'; const chatCompleteBaseRt = t.type({ body: t.intersection([ @@ -57,6 +60,27 @@ const chatCompletePublicRt = t.intersection([ }), ]); +async function guardAgainstInvalidConnector({ + actions, + request, + connectorId, +}: { + actions: ActionsPluginStart; + request: KibanaRequest; + connectorId: string; +}) { + return withAssistantSpan('guard_against_invalid_connector', async () => { + const actionsClient = await actions.getActionsClientWithRequest(request); + + const connector = await actionsClient.get({ + id: connectorId, + throwIfSystemAction: true, + }); + + return connector; + }); +} + const chatRoute = createObservabilityAIAssistantServerRoute({ endpoint: 'POST /internal/observability_ai_assistant/chat', options: { @@ -76,7 +100,17 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ ]), }), handler: async (resources): Promise => { - const { request, params, service, context } = resources; + const { request, params, service, context, plugins } = resources; + + const { + body: { name, messages, connectorId, functions, functionCall }, + } = params; + + await guardAgainstInvalidConnector({ + actions: await plugins.actions.start(), + request, + connectorId, + }); const [client, cloudStart, simulateFunctionCalling] = await Promise.all([ service.getClient({ request }), @@ -88,17 +122,13 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ throw notImplemented(); } - const { - body: { name, messages, connectorId, functions, functionCall }, - } = params; - const controller = new AbortController(); request.events.aborted$.subscribe(() => { controller.abort(); }); - const response$ = await client.chat(name, { + const response$ = client.chat(name, { messages, connectorId, signal: controller.signal, @@ -120,19 +150,7 @@ async function chatComplete( params: t.TypeOf; } ) { - const { request, params, service } = resources; - - const [client, cloudStart, simulateFunctionCalling] = await Promise.all([ - service.getClient({ request }), - resources.plugins.cloud?.start() || Promise.resolve(undefined), - ( - await resources.context.core - ).uiSettings.client.get(aiAssistantSimulatedFunctionCalling), - ]); - - if (!client) { - throw notImplemented(); - } + const { request, params, service, plugins } = resources; const { body: { @@ -147,6 +165,24 @@ async function chatComplete( }, } = params; + await guardAgainstInvalidConnector({ + actions: await plugins.actions.start(), + request, + connectorId, + }); + + const [client, cloudStart, simulateFunctionCalling] = await Promise.all([ + service.getClient({ request }), + resources.plugins.cloud?.start() || Promise.resolve(undefined), + ( + await resources.context.core + ).uiSettings.client.get(aiAssistantSimulatedFunctionCalling), + ]); + + if (!client) { + throw notImplemented(); + } + const controller = new AbortController(); request.events.aborted$.subscribe(() => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts index 9ecbd450cba30..bdce24d65d2c7 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts @@ -48,7 +48,6 @@ describe('chatFunctionClient', () => { }), messages: [], signal: new AbortController().signal, - connectorId: '', }); }).rejects.toThrowError(`Function arguments are invalid`); @@ -107,7 +106,6 @@ describe('chatFunctionClient', () => { name: 'get_data_on_screen', args: JSON.stringify({ data: ['my_dummy_data'] }), messages: [], - connectorId: '', signal: new AbortController().signal, }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts index d0b019d635c12..e882616e202cc 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts @@ -13,7 +13,7 @@ import { FunctionVisibility, type FunctionResponse } from '../../../common/funct import type { Message, ObservabilityAIAssistantScreenContextRequest } from '../../../common/types'; import { filterFunctionDefinitions } from '../../../common/utils/filter_function_definitions'; import type { - ChatFn, + FunctionCallChatFunction, FunctionHandler, FunctionHandlerRegistry, RegisteredInstruction, @@ -144,14 +144,12 @@ export class ChatFunctionClient { args, messages, signal, - connectorId, }: { - chat: ChatFn; + chat: FunctionCallChatFunction; name: string; args: string | undefined; messages: Message[]; signal: AbortSignal; - connectorId: string; }): Promise { const fn = this.functionRegistry.get(name); @@ -167,7 +165,6 @@ export class ChatFunctionClient { { arguments: parsedArguments, messages, - connectorId, screenContexts: this.screenContexts, chat, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.test.ts index 90f7d6f5ee69c..6aef5fb091185 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.test.ts @@ -11,9 +11,9 @@ import { Logger } from '@kbn/logging'; import { concatenateChatCompletionChunks } from '../../../../../common/utils/concatenate_chat_completion_chunks'; import { processBedrockStream } from './process_bedrock_stream'; import { MessageRole } from '../../../../../common'; -import { rejectTokenCountEvents } from '../../../util/reject_token_count_events'; import { TOOL_USE_END, TOOL_USE_START } from '../simulate_function_calling/constants'; import { parseInlineFunctionCalls } from '../simulate_function_calling/parse_inline_function_calls'; +import { withoutTokenCountEvents } from '../../../../../common/utils/without_token_count_events'; describe('processBedrockStream', () => { const encodeChunk = (body: unknown) => { @@ -69,7 +69,7 @@ describe('processBedrockStream', () => { parseInlineFunctionCalls({ logger: getLoggerMock(), }), - rejectTokenCountEvents(), + withoutTokenCountEvents(), concatenateChatCompletionChunks() ) ) @@ -101,7 +101,7 @@ describe('processBedrockStream', () => { parseInlineFunctionCalls({ logger: getLoggerMock(), }), - rejectTokenCountEvents(), + withoutTokenCountEvents(), concatenateChatCompletionChunks() ) ) @@ -135,7 +135,7 @@ describe('processBedrockStream', () => { parseInlineFunctionCalls({ logger: getLoggerMock(), }), - rejectTokenCountEvents(), + withoutTokenCountEvents(), concatenateChatCompletionChunks() ) ) @@ -167,7 +167,7 @@ describe('processBedrockStream', () => { parseInlineFunctionCalls({ logger: getLoggerMock(), }), - rejectTokenCountEvents(), + withoutTokenCountEvents(), concatenateChatCompletionChunks() ) ); @@ -193,7 +193,7 @@ describe('processBedrockStream', () => { parseInlineFunctionCalls({ logger: getLoggerMock(), }), - rejectTokenCountEvents(), + withoutTokenCountEvents(), concatenateChatCompletionChunks() ) ) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/fail_on_non_existing_function_call.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/fail_on_non_existing_function_call.ts index 1e99fd623052b..d4c7c40e440ce 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/fail_on_non_existing_function_call.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/fail_on_non_existing_function_call.ts @@ -5,28 +5,24 @@ * 2.0. */ -import { noop } from 'lodash'; -import { forkJoin, last, Observable, shareReplay, tap } from 'rxjs'; -import { - ChatCompletionChunkEvent, - createFunctionNotFoundError, - FunctionDefinition, -} from '../../../../common'; -import { TokenCountEvent } from '../../../../common/conversation_complete'; +import { ignoreElements, last, merge, Observable, shareReplay, tap } from 'rxjs'; +import { createFunctionNotFoundError, FunctionDefinition } from '../../../../common'; +import { ChatEvent } from '../../../../common/conversation_complete'; import { concatenateChatCompletionChunks } from '../../../../common/utils/concatenate_chat_completion_chunks'; -import { rejectTokenCountEvents } from '../../util/reject_token_count_events'; +import { withoutTokenCountEvents } from '../../../../common/utils/without_token_count_events'; export function failOnNonExistingFunctionCall({ functions, }: { functions?: Array>; }) { - return (source$: Observable) => { - return new Observable((subscriber) => { - const shared = source$.pipe(shareReplay()); + return (source$: Observable) => { + const shared$ = source$.pipe(shareReplay()); - const checkFunctionCallResponse$ = shared.pipe( - rejectTokenCountEvents(), + return merge( + shared$, + shared$.pipe( + withoutTokenCountEvents(), concatenateChatCompletionChunks(), last(), tap((event) => { @@ -36,24 +32,9 @@ export function failOnNonExistingFunctionCall({ ) { throw createFunctionNotFoundError(event.message.function_call.name); } - }) - ); - - source$.subscribe({ - next: (val) => { - subscriber.next(val); - }, - error: noop, - }); - - forkJoin([source$, checkFunctionCallResponse$]).subscribe({ - complete: () => { - subscriber.complete(); - }, - error: (error) => { - subscriber.error(error); - }, - }); - }); + }), + ignoreElements() + ) + ); }; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/types.ts index 3dd2c4bbed5f3..2a292035acdb2 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/types.ts @@ -9,10 +9,7 @@ import type { Readable } from 'node:stream'; import type { Observable } from 'rxjs'; import type { Logger } from '@kbn/logging'; import type { Message } from '../../../../common'; -import type { - ChatCompletionChunkEvent, - TokenCountEvent, -} from '../../../../common/conversation_complete'; +import type { ChatEvent } from '../../../../common/conversation_complete'; import { CompatibleJSONSchema } from '../../../../common/functions/types'; export interface LlmFunction { @@ -31,7 +28,5 @@ export type LlmApiAdapterFactory = (options: { export interface LlmApiAdapter { getSubAction: () => { subAction: string; subActionParams: Record }; - streamIntoObservable: ( - readable: Readable - ) => Observable; + streamIntoObservable: (readable: Readable) => Observable; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts new file mode 100644 index 0000000000000..8f05cf144a33b --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts @@ -0,0 +1,35 @@ +/* + * 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 { findLastIndex } from 'lodash'; +import { Message, MessageAddEvent, MessageRole } from '../../../common'; +import { createFunctionRequestMessage } from '../../../common/utils/create_function_request_message'; + +export function getContextFunctionRequestIfNeeded( + messages: Message[] +): MessageAddEvent | undefined { + const indexOfLastUserMessage = findLastIndex( + messages, + (message) => message.message.role === MessageRole.User && !message.message.name + ); + + const hasContextSinceLastUserMessage = messages + .slice(indexOfLastUserMessage) + .some((message) => message.message.name === 'context'); + + if (hasContextSinceLastUserMessage) { + return undefined; + } + + return createFunctionRequestMessage({ + name: 'context', + args: { + queries: [], + categories: [], + }, + }); +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts index a35e50d538bcb..e22f63cf92eb2 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts @@ -39,12 +39,14 @@ const nextTick = () => { return new Promise(process.nextTick); }; -const waitForNextWrite = async (stream: Readable): Promise => { +const waitForNextWrite = async (stream: Readable): Promise => { // this will fire before the client's internal write() promise is // resolved - await new Promise((resolve) => stream.once('data', resolve)); + const response = await new Promise((resolve) => stream.once('data', resolve)); // so we wait another tick to let the client move to the next step await nextTick(); + + return response; }; function createLlmSimulator() { @@ -108,12 +110,7 @@ describe('Observability AI Assistant client', () => { getInstructions: jest.fn(), } as any; - const loggerMock: DeeplyMockedKeys = { - log: jest.fn(), - error: jest.fn(), - debug: jest.fn(), - trace: jest.fn(), - } as any; + let loggerMock: DeeplyMockedKeys = {} as any; const functionClientMock: DeeplyMockedKeys = { executeFunction: jest.fn(), @@ -130,6 +127,18 @@ describe('Observability AI Assistant client', () => { function createClient() { jest.resetAllMocks(); + // uncomment this line for debugging + // const consoleOrPassThrough = console.log.bind(console); + const consoleOrPassThrough = () => {}; + + loggerMock = { + log: jest.fn().mockImplementation(consoleOrPassThrough), + error: jest.fn().mockImplementation(consoleOrPassThrough), + debug: jest.fn().mockImplementation(consoleOrPassThrough), + trace: jest.fn().mockImplementation(consoleOrPassThrough), + isLevelEnabled: jest.fn().mockReturnValue(true), + } as any; + functionClientMock.getFunctions.mockReturnValue([]); functionClientMock.hasFunction.mockImplementation((name) => { return name !== 'context'; @@ -214,24 +223,27 @@ describe('Observability AI Assistant client', () => { beforeEach(async () => { client = createClient(); actionsClientMock.execute - .mockImplementationOnce(() => { + .mockImplementationOnce((body) => { return new Promise((resolve, reject) => { titleLlmPromiseResolve = (title: string) => { const titleLlmSimulator = createLlmSimulator(); - titleLlmSimulator.next({ content: title }); - titleLlmSimulator.complete(); - resolve({ - actionId: '', - status: 'ok', - data: titleLlmSimulator.stream, - }); + titleLlmSimulator + .next({ content: title }) + .then(() => titleLlmSimulator.complete()) + .then(() => { + resolve({ + actionId: '', + status: 'ok', + data: titleLlmSimulator.stream, + }); + }); }; - titleLlmPromiseReject = () => { - reject(); + titleLlmPromiseReject = (error: Error) => { + reject(error); }; }); }) - .mockImplementationOnce(async () => { + .mockImplementationOnce(async (body) => { llmSimulator = createLlmSimulator(); return { actionId: '', @@ -260,6 +272,8 @@ describe('Observability AI Assistant client', () => { stream.on('data', dataHandler); await llmSimulator.next({ content: 'Hello' }); + + await nextTick(); }); it('calls the actions client with the messages', () => { @@ -346,9 +360,9 @@ describe('Observability AI Assistant client', () => { id: expect.any(String), last_updated: expect.any(String), token_count: { - completion: 2, - prompt: 156, - total: 158, + completion: 1, + prompt: 78, + total: 79, }, }, type: StreamingChatResponseEventType.ConversationCreate, @@ -364,8 +378,6 @@ describe('Observability AI Assistant client', () => { titleLlmPromiseResolve('An auto-generated title'); - await nextTick(); - await llmSimulator.complete(); await finished(stream); @@ -405,9 +417,9 @@ describe('Observability AI Assistant client', () => { id: expect.any(String), last_updated: expect.any(String), token_count: { - completion: 8, - prompt: 340, - total: 348, + completion: 6, + prompt: 262, + total: 268, }, }, type: StreamingChatResponseEventType.ConversationCreate, @@ -423,9 +435,9 @@ describe('Observability AI Assistant client', () => { last_updated: expect.any(String), title: 'An auto-generated title', token_count: { - completion: 8, - prompt: 340, - total: 348, + completion: 6, + prompt: 262, + total: 268, }, }, labels: {}, @@ -477,7 +489,7 @@ describe('Observability AI Assistant client', () => { beforeEach(async () => { client = createClient(); - actionsClientMock.execute.mockImplementationOnce(async () => { + actionsClientMock.execute.mockImplementationOnce(async (body) => { llmSimulator = createLlmSimulator(); return { actionId: '', @@ -499,6 +511,11 @@ describe('Observability AI Assistant client', () => { id: 'my-conversation-id', title: 'My stored conversation', last_updated: new Date().toISOString(), + token_count: { + completion: 1, + prompt: 78, + total: 79, + }, }, labels: {}, numeric_labels: {}, @@ -694,7 +711,7 @@ describe('Observability AI Assistant client', () => { beforeEach(async () => { client = createClient(); - actionsClientMock.execute.mockImplementationOnce(async () => { + actionsClientMock.execute.mockImplementationOnce(async (body) => { llmSimulator = createLlmSimulator(); return { actionId: '', @@ -794,7 +811,6 @@ describe('Observability AI Assistant client', () => { it('executes the function', () => { expect(functionClientMock.executeFunction).toHaveBeenCalledWith({ - connectorId: 'foo', name: 'myFunction', chat: expect.any(Function), args: JSON.stringify({ foo: 'bar' }), @@ -832,6 +848,7 @@ describe('Observability AI Assistant client', () => { afterEach(async () => { fnResponseResolve({ content: { my: 'content' } }); + await waitForNextWrite(stream); await llmSimulator.complete(); @@ -993,7 +1010,12 @@ describe('Observability AI Assistant client', () => { }); it('appends the function response', () => { - expect(JSON.parse(dataHandler.mock.lastCall!)).toEqual({ + const parsed = JSON.parse(dataHandler.mock.lastCall!); + + parsed.message.message.content = JSON.parse(parsed.message.message.content); + parsed.message.message.data = JSON.parse(parsed.message.message.data); + + expect(parsed).toEqual({ type: StreamingChatResponseEventType.MessageAdd, id: expect.any(String), message: { @@ -1001,10 +1023,16 @@ describe('Observability AI Assistant client', () => { message: { role: MessageRole.User, name: 'myFunction', - content: JSON.stringify({ - message: 'Error: Function failed', - error: {}, - }), + content: { + message: 'Function failed', + error: { + name: 'Error', + message: 'Function failed', + }, + }, + data: { + stack: expect.any(String), + }, }, }, }); @@ -1138,7 +1166,7 @@ describe('Observability AI Assistant client', () => { let dataHandler: jest.Mock; beforeEach(async () => { client = createClient(); - actionsClientMock.execute.mockImplementationOnce(async () => { + actionsClientMock.execute.mockImplementationOnce(async (body) => { llmSimulator = createLlmSimulator(); return { actionId: '', @@ -1149,7 +1177,7 @@ describe('Observability AI Assistant client', () => { functionClientMock.hasFunction.mockReturnValue(true); - functionClientMock.executeFunction.mockImplementationOnce(async () => { + functionClientMock.executeFunction.mockImplementationOnce(async (body) => { return { content: [ { @@ -1327,14 +1355,14 @@ describe('Observability AI Assistant client', () => { await nextTick(); - for (let i = 0; i <= maxFunctionCalls + 1; i++) { + for (let i = 0; i <= maxFunctionCalls; i++) { await requestAlertsFunctionCall(); } await finished(stream); }); - it('executed the function no more than three times', () => { + it(`executed the function no more than ${maxFunctionCalls} times`, () => { expect(functionClientMock.executeFunction).toHaveBeenCalledTimes(maxFunctionCalls); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts index e4cb53be99754..c00c060bcf138 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts @@ -5,25 +5,27 @@ * 2.0. */ import type { SearchHit } from '@elastic/elasticsearch/lib/api/types'; -import { internal, notFound } from '@hapi/boom'; +import { notFound } from '@hapi/boom'; import type { ActionsClient } from '@kbn/actions-plugin/server'; import type { ElasticsearchClient } from '@kbn/core/server'; import type { Logger } from '@kbn/logging'; import type { PublicMethodsOf } from '@kbn/utility-types'; -import apm from 'elastic-apm-node'; -import { decode, encode } from 'gpt-tokenizer'; -import { findLastIndex, last, merge, noop, omit, pick, take } from 'lodash'; +import { merge, omit } from 'lodash'; import { filter, - identity, - isObservable, - last as lastOperator, - lastValueFrom, + forkJoin, + from, + merge as mergeOperator, map, Observable, + of, shareReplay, + switchMap, + throwError, + combineLatest, tap, - toArray, + catchError, + defer, } from 'rxjs'; import { Readable } from 'stream'; import { v4 } from 'uuid'; @@ -31,20 +33,17 @@ import { ObservabilityAIAssistantConnectorType } from '../../../common/connector import { ChatCompletionChunkEvent, ChatCompletionErrorEvent, + ConversationCreateEvent, + ConversationUpdateEvent, createConversationNotFoundError, + createInternalServerError, createTokenLimitReachedError, - MessageAddEvent, StreamingChatResponseEventType, TokenCountEvent, type StreamingChatResponseEvent, } from '../../../common/conversation_complete'; +import { CompatibleJSONSchema } from '../../../common/functions/types'; import { - CompatibleJSONSchema, - FunctionResponse, - FunctionVisibility, -} from '../../../common/functions/types'; -import { - MessageRole, UserInstruction, type Conversation, type ConversationCreateRequest, @@ -52,25 +51,30 @@ import { type KnowledgeBaseEntry, type Message, } from '../../../common/types'; -import { concatenateChatCompletionChunks } from '../../../common/utils/concatenate_chat_completion_chunks'; -import { createFunctionResponseError } from '../../../common/utils/create_function_response_error'; -import { emitWithConcatenatedMessage } from '../../../common/utils/emit_with_concatenated_message'; +import { withoutTokenCountEvents } from '../../../common/utils/without_token_count_events'; import type { ChatFunctionClient } from '../chat_function_client'; import { KnowledgeBaseEntryOperationType, KnowledgeBaseService, RecalledEntry, } from '../knowledge_base_service'; -import type { ChatFn, ObservabilityAIAssistantResourceNames } from '../types'; -import { catchFunctionLimitExceededError } from '../util/catch_function_limit_exceeded_error'; +import type { ObservabilityAIAssistantResourceNames } from '../types'; import { getAccessQuery } from '../util/get_access_query'; import { getSystemMessageFromInstructions } from '../util/get_system_message_from_instructions'; -import { rejectTokenCountEvents } from '../util/reject_token_count_events'; import { replaceSystemMessage } from '../util/replace_system_message'; +import { withAssistantSpan } from '../util/with_assistant_span'; import { createBedrockClaudeAdapter } from './adapters/bedrock/bedrock_claude_adapter'; import { failOnNonExistingFunctionCall } from './adapters/fail_on_non_existing_function_call'; import { createOpenAiAdapter } from './adapters/openai_adapter'; import { LlmApiAdapter } from './adapters/types'; +import { getContextFunctionRequestIfNeeded } from './get_context_function_request_if_needed'; +import { extractMessages } from './operators/extract_messages'; +import { extractTokenCount } from './operators/extract_token_count'; +import { instrumentAndCountTokens } from './operators/instrument_and_count_tokens'; +import { continueConversation } from './operators/continue_conversation'; +import { getGeneratedTitle } from './operators/get_generated_title'; + +const MAX_FUNCTION_CALLS = 8; export class ObservabilityAIAssistantClient { constructor( @@ -161,472 +165,273 @@ export class ObservabilityAIAssistantClient { instructions?: Array; simulateFunctionCalling?: boolean; }): Observable> => { - return new Observable>( - (subscriber) => { - const { - messages, - connectorId, - signal, - functionClient, - persist, - kibanaPublicUrl, - simulateFunctionCalling, - isPublic = false, - instructions: requestInstructions = [], - } = params; - - const isConversationUpdate = persist && !!params.conversationId; - const conversationId = persist ? params.conversationId || v4() : ''; - const title = params.title || ''; - const responseLanguage = params.responseLanguage || 'English'; - - const registeredInstructions = functionClient.getInstructions(); - - const knowledgeBaseInstructions: UserInstruction[] = []; - - if (responseLanguage) { - requestInstructions.push( - `You MUST respond in the users preferred language which is: ${responseLanguage}.` - ); - } - - let storedSystemMessage: string = ''; // will be set as soon as kb instructions are loaded - - if (persist && !isConversationUpdate && kibanaPublicUrl) { - registeredInstructions.push( - `This conversation will be persisted in Kibana and available at this url: ${ - kibanaPublicUrl + `/app/observabilityAIAssistant/conversations/${conversationId}` - }.` - ); - } - - const tokenCountResult = { - prompt: 0, - completion: 0, - total: 0, - }; - - const chatWithTokenCountIncrement: ChatFn = async (name, options) => { - const response$ = await this.chat(name, { - ...options, - simulateFunctionCalling, - }); - - const incrementTokenCount = () => { - return ( - source: Observable - ): Observable => { - return source.pipe( - tap((event) => { - if (event.type === StreamingChatResponseEventType.TokenCount) { - tokenCountResult.prompt += event.tokens.prompt; - tokenCountResult.completion += event.tokens.completion; - tokenCountResult.total += event.tokens.total; - } - }) - ); - }; - }; - - return response$.pipe(incrementTokenCount(), rejectTokenCountEvents()); - }; - - let numFunctionsCalled: number = 0; - - const MAX_FUNCTION_CALLS = 8; - const MAX_FUNCTION_RESPONSE_TOKEN_COUNT = 4000; - - const allFunctions = functionClient - .getFunctions() - .filter((fn) => { - const visibility = fn.definition.visibility ?? FunctionVisibility.All; - return ( - visibility === FunctionVisibility.All || - visibility === FunctionVisibility.AssistantOnly - ); - }) - .map((fn) => pick(fn.definition, 'name', 'description', 'parameters')); - - const allActions = functionClient.getActions(); + const { + functionClient, + connectorId, + simulateFunctionCalling, + instructions: requestInstructions = [], + messages: initialMessages, + signal, + responseLanguage = 'English', + persist, + kibanaPublicUrl, + isPublic, + title: predefinedTitle, + conversationId: predefinedConversationId, + } = params; + + if (responseLanguage) { + requestInstructions.push( + `You MUST respond in the users preferred language which is: ${responseLanguage}.` + ); + } - const next = async (nextMessages: Message[]): Promise => { - const lastMessage = last(nextMessages); - const isUserMessage = lastMessage?.message.role === MessageRole.User; + const isConversationUpdate = persist && !!predefinedConversationId; - const indexOfLastUserMessage = findLastIndex( - nextMessages, - ({ message }) => message.role === MessageRole.User && !message.name - ); + const conversationId = persist ? predefinedConversationId || v4() : ''; - const hasNoContextRequestAfterLastUserMessage = - indexOfLastUserMessage !== -1 && - nextMessages - .slice(indexOfLastUserMessage) - .every(({ message }) => message.function_call?.name !== 'context'); + if (persist && !isConversationUpdate && kibanaPublicUrl) { + requestInstructions.push( + `This conversation will be persisted in Kibana and available at this url: ${ + kibanaPublicUrl + `/app/observabilityAIAssistant/conversations/${conversationId}` + }.` + ); + } - const shouldInjectContext = - functionClient.hasFunction('context') && hasNoContextRequestAfterLastUserMessage; + const kbInstructions$ = from(this.fetchKnowledgeBaseInstructions()).pipe(shareReplay()); + + // from the initial messages, override any system message with + // the one that is based on the instructions (registered, request, kb) + const messagesWithUpdatedSystemMessage$ = kbInstructions$.pipe( + map((knowledgeBaseInstructions) => { + // this is what we eventually store in the conversation + const messagesWithUpdatedSystemMessage = replaceSystemMessage( + getSystemMessageFromInstructions({ + registeredInstructions: functionClient.getInstructions(), + knowledgeBaseInstructions, + requestInstructions, + availableFunctionNames: functionClient.getFunctions().map((fn) => fn.definition.name), + }), + initialMessages + ); + + return messagesWithUpdatedSystemMessage; + }), + shareReplay() + ); - if (shouldInjectContext) { - const contextFunctionRequest = { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.Assistant, - content: '', - function_call: { - name: 'context', - arguments: JSON.stringify({ - queries: [], - categories: [], - }), - trigger: MessageRole.Assistant as const, + // if it is: + // - a new conversation + // - no predefined title is given + // - we need to store the conversation + // we generate a title + // if not, we complete with an empty string + const title$ = + predefinedTitle || isConversationUpdate || !persist + ? of(predefinedTitle || '').pipe(shareReplay()) + : messagesWithUpdatedSystemMessage$.pipe( + switchMap((messages) => + getGeneratedTitle({ + messages, + responseLanguage, + logger: this.dependencies.logger, + chat: (name, chatParams) => { + return this.chat(name, { + ...chatParams, + simulateFunctionCalling, + connectorId, + signal, + }); }, - }, - }; - - subscriber.next({ - type: StreamingChatResponseEventType.MessageAdd, - id: v4(), - message: contextFunctionRequest, - }); - - return await next(nextMessages.concat(contextFunctionRequest)); - } else if (isUserMessage) { - const functionCallsExceeded = numFunctionsCalled > MAX_FUNCTION_CALLS; - const functions = functionCallsExceeded ? [] : allFunctions.concat(allActions); - - const spanName = - lastMessage.message.name && lastMessage.message.name !== 'context' - ? 'function_response' - : 'user_message'; - - const systemMessageForChatRequest = getSystemMessageFromInstructions({ - registeredInstructions, - requestInstructions, - knowledgeBaseInstructions, - availableFunctionNames: functions.map((fn) => fn.name) || [], - }); - - const response$ = ( - await chatWithTokenCountIncrement(spanName, { - messages: replaceSystemMessage(systemMessageForChatRequest, nextMessages), - connectorId, - signal, - functions, }) - ).pipe( - emitWithConcatenatedMessage(), - shareReplay(), - Boolean(functions.length) ? identity : catchFunctionLimitExceededError() - ); - - response$.subscribe({ - next: (val) => subscriber.next(val), - // we handle the error below - error: noop, - }); - - const emittedMessageEvents = await lastValueFrom( - response$.pipe( - filter( - (event): event is MessageAddEvent => - event.type === StreamingChatResponseEventType.MessageAdd - ), - // LLMs like to hallucinate parameters if the function does not define - // them, and it can lead to other hallicunations down the line - map((messageEvent) => { - const fnName = messageEvent.message.message.function_call?.name; - - if (fnName && !functions.find((fn) => fn.name === fnName)?.parameters) { - const clone = { ...messageEvent }; - clone.message.message.function_call!.arguments = ''; - return clone; - } - return messageEvent; - }), - toArray() - ) - ); - - return await next( - nextMessages.concat(emittedMessageEvents.map((event) => event.message)) - ); - } - - const functionCallName = lastMessage?.message.function_call?.name; - const isAssistantMessage = lastMessage?.message.role === MessageRole.Assistant; - - if (isAssistantMessage && functionCallName) { - if (functionClient.hasAction(functionCallName)) { - this.dependencies.logger.debug(`Executing client-side action: ${functionCallName}`); - - // if validation fails, return the error to the LLM. - // otherwise, close the stream. - - try { - functionClient.validate( - functionCallName, - JSON.parse(lastMessage.message.function_call!.arguments || '{}') - ); - } catch (error) { - const functionResponseMessage = createFunctionResponseError({ - name: functionCallName, - error, - }); - nextMessages = nextMessages.concat(functionResponseMessage.message); - - subscriber.next(functionResponseMessage); - - return await next(nextMessages); - } - - subscriber.complete(); - - return; - } - - const span = apm.startSpan(`execute_function ${functionCallName}`); - - span?.addLabels({ - ai_assistant_args: JSON.stringify(lastMessage.message.function_call!.arguments ?? {}), - }); - - const functionResponse = - numFunctionsCalled >= MAX_FUNCTION_CALLS - ? { - content: { - error: {}, - message: 'Function limit exceeded, ask the user what to do next', - }, - } - : await functionClient - .executeFunction({ - chat: chatWithTokenCountIncrement, - connectorId, - name: functionCallName, - messages: replaceSystemMessage(storedSystemMessage, nextMessages), - args: lastMessage.message.function_call!.arguments, - signal, - }) - .then((response) => { - if (isObservable(response)) { - return response; - } - - span?.setOutcome('success'); - - const encoded = encode(JSON.stringify(response.content || {})); - - if (encoded.length <= MAX_FUNCTION_RESPONSE_TOKEN_COUNT) { - return response; - } - - return { - data: response.data, - content: { - message: - 'Function response exceeded the maximum length allowed and was truncated', - truncated: decode(take(encoded, MAX_FUNCTION_RESPONSE_TOKEN_COUNT)), - }, - }; - }) - .catch((error): FunctionResponse => { - span?.setOutcome('failure'); - return { - content: { - message: error.toString(), - error, - }, - }; - }); - - numFunctionsCalled++; - - if (signal.aborted) { - span?.end(); - return; - } - - if (isObservable(functionResponse)) { - const shared = functionResponse.pipe(shareReplay()); + ), + shareReplay() + ); - shared.subscribe({ - next: (val) => subscriber.next(val), - // we handle the error below - error: noop, + // we continue the conversation here, after resolving both the materialized + // messages and the knowledge base instructions + const nextEvents$ = combineLatest([messagesWithUpdatedSystemMessage$, kbInstructions$]).pipe( + switchMap(([messagesWithUpdatedSystemMessage, knowledgeBaseInstructions]) => { + // if needed, inject a context function request here + const contextRequest = functionClient.hasFunction('context') + ? getContextFunctionRequestIfNeeded(messagesWithUpdatedSystemMessage) + : undefined; + + return mergeOperator( + // if we have added a context function request, also emit + // the messageAdd event for it, so we can notify the consumer + // and add it to the conversation + ...(contextRequest ? [of(contextRequest)] : []), + continueConversation({ + messages: [ + ...messagesWithUpdatedSystemMessage, + ...(contextRequest ? [contextRequest.message] : []), + ], + chat: (name, chatParams) => { + // inject a chat function with predefined parameters + return this.chat(name, { + ...chatParams, + signal, + simulateFunctionCalling, + connectorId, }); + }, + // start out with the max number of function calls + functionCallsLeft: MAX_FUNCTION_CALLS, + functionClient, + knowledgeBaseInstructions, + requestInstructions, + signal, + }) + ); + }), + shareReplay() + ); - const messageEvents = await lastValueFrom( - shared.pipe( - filter( - (event): event is MessageAddEvent => - event.type === StreamingChatResponseEventType.MessageAdd - ), - toArray() - ) - ); - - span?.end(); - - return await next(nextMessages.concat(messageEvents.map((event) => event.message))); - } - - const functionResponseMessage = { - '@timestamp': new Date().toISOString(), - message: { - name: lastMessage.message.function_call!.name, - - content: JSON.stringify(functionResponse.content || {}), - data: functionResponse.data ? JSON.stringify(functionResponse.data) : undefined, - role: MessageRole.User, - }, - }; - - this.dependencies.logger.debug( - `Function response: ${JSON.stringify(functionResponseMessage, null, 2)}` - ); - nextMessages = nextMessages.concat(functionResponseMessage); - - subscriber.next({ - type: StreamingChatResponseEventType.MessageAdd, - message: functionResponseMessage, - id: v4(), - }); - - span?.end(); - - return await next(nextMessages); - } - - this.dependencies.logger.debug(`Conversation: ${JSON.stringify(nextMessages, null, 2)}`); - - if (!persist) { - subscriber.complete(); - return; + const output$ = mergeOperator( + // get all the events from continuing the conversation + nextEvents$, + // wait until all dependencies have completed + forkJoin([ + messagesWithUpdatedSystemMessage$, + // get just the new messages + nextEvents$.pipe(withoutTokenCountEvents(), extractMessages()), + // count all the token count events emitted during completion + mergeOperator( + nextEvents$, + title$.pipe(filter((value): value is TokenCountEvent => typeof value !== 'string')) + ).pipe(extractTokenCount()), + // get just the title, and drop the token count events + title$.pipe(filter((value): value is string => typeof value === 'string')), + ]).pipe( + switchMap(([messagesWithUpdatedSystemMessage, addedMessages, tokenCountResult, title]) => { + const initialMessagesWithAddedMessages = + messagesWithUpdatedSystemMessage.concat(addedMessages); + + const lastMessage = + initialMessagesWithAddedMessages[initialMessagesWithAddedMessages.length - 1]; + + // if a function request is at the very end, close the stream to consumer + // without persisting or updating the conversation. we need to wait + // on the function response to have a valid conversation + const isFunctionRequest = lastMessage.message.function_call?.name; + + if (!persist || isFunctionRequest) { + return of(); } - this.dependencies.logger.debug( - `Token count for conversation: ${JSON.stringify(tokenCountResult)}` - ); - - apm.currentTransaction?.addLabels({ - tokenCountPrompt: tokenCountResult.prompt, - tokenCountCompletion: tokenCountResult.completion, - tokenCountTotal: tokenCountResult.total, - }); - - // store the updated conversation and close the stream if (isConversationUpdate) { - const conversation = await this.getConversationWithMetaFields(conversationId); - if (!conversation) { - throw createConversationNotFoundError(); - } - - if (signal.aborted) { - return; - } - - const persistedTokenCount = conversation._source?.conversation.token_count; - - const updatedConversation = await this.update( - conversationId, - - merge( - {}, - - // base conversation without messages - omit(conversation._source, 'messages'), - - // update messages - { messages: replaceSystemMessage(storedSystemMessage, nextMessages) }, + return from(this.getConversationWithMetaFields(conversationId)) + .pipe( + switchMap((conversation) => { + if (!conversation) { + return throwError(() => createConversationNotFoundError()); + } - // update token count - { - conversation: { - token_count: { - prompt: (persistedTokenCount?.prompt || 0) + tokenCountResult.prompt, - completion: - (persistedTokenCount?.completion || 0) + tokenCountResult.completion, - total: (persistedTokenCount?.total || 0) + tokenCountResult.total, - }, - }, - } + const persistedTokenCount = conversation._source?.conversation.token_count ?? { + prompt: 0, + completion: 0, + total: 0, + }; + + return from( + this.update( + conversationId, + + merge( + {}, + + // base conversation without messages + omit(conversation._source, 'messages'), + + // update messages + { messages: initialMessagesWithAddedMessages }, + + // update token count + { + conversation: { + title: title || conversation._source?.conversation.title, + token_count: { + prompt: persistedTokenCount.prompt + tokenCountResult.prompt, + completion: + persistedTokenCount.completion + tokenCountResult.completion, + total: persistedTokenCount.total + tokenCountResult.total, + }, + }, + } + ) + ) + ); + }) ) - ); - - subscriber.next({ - type: StreamingChatResponseEventType.ConversationUpdate, - conversation: updatedConversation.conversation, - }); - } else { - const generatedTitle = await titlePromise; - if (signal.aborted) { - return; - } + .pipe( + map((conversation): ConversationUpdateEvent => { + return { + conversation: conversation.conversation, + type: StreamingChatResponseEventType.ConversationUpdate, + }; + }) + ); + } - const conversation = await this.create({ + return from( + this.create({ '@timestamp': new Date().toISOString(), conversation: { - title: generatedTitle || title || 'New conversation', - token_count: tokenCountResult, + title, id: conversationId, + token_count: tokenCountResult, }, - messages: replaceSystemMessage(storedSystemMessage, nextMessages), + public: !!isPublic, labels: {}, numeric_labels: {}, - public: isPublic, - }); - - subscriber.next({ - type: StreamingChatResponseEventType.ConversationCreate, - conversation: conversation.conversation, - }); - } - - subscriber.complete(); - }; - - this.fetchKnowledgeBaseInstructions() - .then((loadedKnowledgeBaseInstructions) => { - knowledgeBaseInstructions.push(...loadedKnowledgeBaseInstructions); - - storedSystemMessage = getSystemMessageFromInstructions({ - registeredInstructions, - requestInstructions, - knowledgeBaseInstructions, - availableFunctionNames: allFunctions.map((fn) => fn.name), - }); + messages: initialMessagesWithAddedMessages, + }) + ).pipe( + map((conversation): ConversationCreateEvent => { + return { + conversation: conversation.conversation, + type: StreamingChatResponseEventType.ConversationCreate, + }; + }) + ); + }) + ) + ); - return next(messages); - }) - .catch((error) => { - if (!signal.aborted) { - this.dependencies.logger.error(error); - } - subscriber.error(error); - }); + return output$.pipe( + instrumentAndCountTokens('complete'), + withoutTokenCountEvents(), + catchError((error) => { + this.dependencies.logger.error(error); + return throwError(() => error); + }), + tap((event) => { + if (this.dependencies.logger.isLevelEnabled('debug')) { + switch (event.type) { + case StreamingChatResponseEventType.MessageAdd: + this.dependencies.logger.debug(`Added message: ${JSON.stringify(event.message)}`); + break; + + case StreamingChatResponseEventType.ConversationCreate: + this.dependencies.logger.debug( + `Created conversation: ${JSON.stringify(event.conversation)}` + ); + break; - const titlePromise = - !isConversationUpdate && !title && persist - ? this.getGeneratedTitle({ - chat: chatWithTokenCountIncrement, - messages, - connectorId, - signal, - responseLanguage, - }).catch((error) => { - this.dependencies.logger.error( - 'Could not generate title, falling back to default title' - ); - this.dependencies.logger.error(error); - return Promise.resolve(undefined); - }) - : Promise.resolve(undefined); - } - ).pipe(shareReplay()); + case StreamingChatResponseEventType.ConversationUpdate: + this.dependencies.logger.debug( + `Updated conversation: ${JSON.stringify(event.conversation)}` + ); + break; + } + } + }), + shareReplay() + ); }; - chat = async ( + chat = ( name: string, { messages, @@ -643,123 +448,96 @@ export class ObservabilityAIAssistantClient { signal: AbortSignal; simulateFunctionCalling?: boolean; } - ): Promise> => { - const span = apm.startSpan(`chat ${name}`); - - const spanId = (span?.ids['span.id'] || '').substring(0, 6); - - const loggerPrefix = `${name}${spanId ? ` (${spanId})` : ''}`; - - try { - const connector = await this.dependencies.actionsClient.get({ - id: connectorId, - }); - - let adapter: LlmApiAdapter; - - this.dependencies.logger.debug(`Creating "${connector.actionTypeId}" adapter`); - - switch (connector.actionTypeId) { - case ObservabilityAIAssistantConnectorType.OpenAI: - adapter = createOpenAiAdapter({ - messages, - functions, - functionCall, - logger: this.dependencies.logger, - simulateFunctionCalling, - }); - break; - - case ObservabilityAIAssistantConnectorType.Bedrock: - adapter = createBedrockClaudeAdapter({ - messages, - functions, - functionCall, - logger: this.dependencies.logger, - }); - break; - - default: - throw new Error(`Connector type is not supported: ${connector.actionTypeId}`); - } - - const subAction = adapter.getSubAction(); - - this.dependencies.logger.debug(`${loggerPrefix}: Sending conversation to connector`); - this.dependencies.logger.trace( - `${loggerPrefix}:\n${JSON.stringify(subAction.subActionParams, null, 2)}` - ); - - const now = performance.now(); - - const executeResult = await this.dependencies.actionsClient.execute({ - actionId: connectorId, - params: subAction, - }); - - this.dependencies.logger.debug( - `${loggerPrefix}: Received action client response: ${ - executeResult.status - } (took: ${Math.round(performance.now() - now)}ms)` - ); - - if (executeResult.status === 'error' && executeResult?.serviceMessage) { - const tokenLimitRegex = - /This model's maximum context length is (\d+) tokens\. However, your messages resulted in (\d+) tokens/g; - const tokenLimitRegexResult = tokenLimitRegex.exec(executeResult.serviceMessage); + ): Observable => { + return defer(() => + from( + withAssistantSpan('get_connector', () => + this.dependencies.actionsClient.get({ id: connectorId, throwIfSystemAction: true }) + ) + ) + ).pipe( + switchMap((connector) => { + this.dependencies.logger.debug(`Creating "${connector.actionTypeId}" adapter`); + + let adapter: LlmApiAdapter; + + switch (connector.actionTypeId) { + case ObservabilityAIAssistantConnectorType.OpenAI: + adapter = createOpenAiAdapter({ + messages, + functions, + functionCall, + logger: this.dependencies.logger, + simulateFunctionCalling, + }); + break; + + case ObservabilityAIAssistantConnectorType.Bedrock: + adapter = createBedrockClaudeAdapter({ + messages, + functions, + functionCall, + logger: this.dependencies.logger, + }); + break; - if (tokenLimitRegexResult) { - const [, tokenLimit, tokenCount] = tokenLimitRegexResult; - throw createTokenLimitReachedError(parseInt(tokenLimit, 10), parseInt(tokenCount, 10)); + default: + throw new Error(`Connector type is not supported: ${connector.actionTypeId}`); } - } - if (executeResult.status === 'error') { - throw internal(`${executeResult?.message} - ${executeResult?.serviceMessage}`); - } + const subAction = adapter.getSubAction(); + + this.dependencies.logger.trace(JSON.stringify(subAction.subActionParams, null, 2)); + + return from( + withAssistantSpan('get_execute_result', () => + this.dependencies.actionsClient.execute({ + actionId: connectorId, + params: subAction, + }) + ) + ).pipe( + switchMap((executeResult) => { + if (executeResult.status === 'error' && executeResult?.serviceMessage) { + const tokenLimitRegex = + /This model's maximum context length is (\d+) tokens\. However, your messages resulted in (\d+) tokens/g; + const tokenLimitRegexResult = tokenLimitRegex.exec(executeResult.serviceMessage); + + if (tokenLimitRegexResult) { + const [, tokenLimit, tokenCount] = tokenLimitRegexResult; + throw createTokenLimitReachedError( + parseInt(tokenLimit, 10), + parseInt(tokenCount, 10) + ); + } + } - const response = executeResult.data as Readable; + if (executeResult.status === 'error') { + throw createInternalServerError( + `${executeResult?.message} - ${executeResult?.serviceMessage}` + ); + } - signal.addEventListener('abort', () => response.destroy()); + const response = executeResult.data as Readable; - const response$ = adapter.streamIntoObservable(response).pipe( - shareReplay(), - failOnNonExistingFunctionCall({ functions }), - tap((event) => { - if (event.type === StreamingChatResponseEventType.TokenCount) { - span?.addLabels({ - tokenCountPrompt: event.tokens.prompt, - tokenCountCompletion: event.tokens.completion, - tokenCountTotal: event.tokens.total, - }); - } - }) - ); + signal.addEventListener('abort', () => response.destroy()); - response$ - .pipe(rejectTokenCountEvents(), concatenateChatCompletionChunks(), lastOperator()) - .subscribe({ - error: (error) => { - this.dependencies.logger.debug('Error in chat response'); - this.dependencies.logger.debug(error); - span?.setOutcome('failure'); - span?.end(); - }, - next: (message) => { - this.dependencies.logger.debug(`Received message:\n${JSON.stringify(message)}`); - }, - complete: () => { - span?.setOutcome('success'); - span?.end(); - }, - }); - - return response$; - } catch (error) { - span?.setOutcome('failure'); - span?.end(); - throw error; - } + return adapter.streamIntoObservable(response); + }) + ); + }), + instrumentAndCountTokens(name), + failOnNonExistingFunctionCall({ functions }), + tap((event) => { + if ( + event.type === StreamingChatResponseEventType.ChatCompletionChunk && + this.dependencies.logger.isLevelEnabled('trace') + ) { + this.dependencies.logger.trace(`Received chunk: ${JSON.stringify(event.message)}`); + } + }), + shareReplay() + ); }; find = async (options?: { query?: string }): Promise<{ conversations: Conversation[] }> => { @@ -813,79 +591,6 @@ export class ObservabilityAIAssistantClient { return updatedConversation; }; - getGeneratedTitle = async ({ - chat, - messages, - connectorId, - signal, - responseLanguage, - }: { - chat: ( - ...chatParams: Parameters['chat']> - ) => Promise>; - messages: Message[]; - connectorId: string; - signal: AbortSignal; - responseLanguage: string; - }) => { - const response$ = await chat('generate_title', { - messages: [ - { - '@timestamp': new Date().toString(), - message: { - role: MessageRole.System, - content: `You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you. Please create the title in ${responseLanguage}.`, - }, - }, - { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.User, - content: messages.slice(1).reduce((acc, curr) => { - return `${acc} ${curr.message.role}: ${curr.message.content}`; - }, 'Generate a title, using the title_conversation_function, based on the following conversation:\n\n'), - }, - }, - ], - functions: [ - { - name: 'title_conversation', - description: - 'Use this function to title the conversation. Do not wrap the title in quotes', - parameters: { - type: 'object', - properties: { - title: { - type: 'string', - }, - }, - required: ['title'], - }, - }, - ], - functionCall: 'title_conversation', - connectorId, - signal, - }); - - const response = await lastValueFrom(response$.pipe(concatenateChatCompletionChunks())); - - const input = - (response.message.function_call.name - ? JSON.parse(response.message.function_call.arguments).title - : response.message?.content) || ''; - - // This regular expression captures a string enclosed in single or double quotes. - // It extracts the string content without the quotes. - // Example matches: - // - "Hello, World!" => Captures: Hello, World! - // - 'Another Example' => Captures: Another Example - // - JustTextWithoutQuotes => Captures: JustTextWithoutQuotes - const match = input.match(/^["']?([^"']+)["']?$/); - const title = match ? match[1] : input; - return title; - }; - setTitle = async ({ conversationId, title }: { conversationId: string; title: string }) => { const document = await this.getConversationWithMetaFields(conversationId); if (!document) { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts new file mode 100644 index 0000000000000..a4a87c4dbe545 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts @@ -0,0 +1,294 @@ +/* + * 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 { decode, encode } from 'gpt-tokenizer'; +import { pick, take } from 'lodash'; +import { + catchError, + concat, + EMPTY, + from, + isObservable, + Observable, + of, + OperatorFunction, + shareReplay, + switchMap, + throwError, +} from 'rxjs'; +import { createFunctionNotFoundError, Message, MessageRole } from '../../../../common'; +import { + createFunctionLimitExceededError, + MessageOrChatEvent, +} from '../../../../common/conversation_complete'; +import { FunctionVisibility } from '../../../../common/functions/types'; +import { UserInstruction } from '../../../../common/types'; +import { createFunctionResponseError } from '../../../../common/utils/create_function_response_error'; +import { createFunctionResponseMessage } from '../../../../common/utils/create_function_response_message'; +import { emitWithConcatenatedMessage } from '../../../../common/utils/emit_with_concatenated_message'; +import { withoutTokenCountEvents } from '../../../../common/utils/without_token_count_events'; +import type { ChatFunctionClient } from '../../chat_function_client'; +import type { ChatFunctionWithoutConnector } from '../../types'; +import { getSystemMessageFromInstructions } from '../../util/get_system_message_from_instructions'; +import { replaceSystemMessage } from '../../util/replace_system_message'; +import { extractMessages } from './extract_messages'; +import { hideTokenCountEvents } from './hide_token_count_events'; + +const MAX_FUNCTION_RESPONSE_TOKEN_COUNT = 4000; + +function executeFunctionAndCatchError({ + name, + args, + functionClient, + messages, + chat, + signal, +}: { + name: string; + args: string | undefined; + functionClient: ChatFunctionClient; + messages: Message[]; + chat: ChatFunctionWithoutConnector; + signal: AbortSignal; +}): Observable { + // hide token count events from functions to prevent them from + // having to deal with it as well + return hideTokenCountEvents((hide) => { + const executeFunctionResponse$ = from( + functionClient.executeFunction({ + name, + chat: (operationName, params) => { + return chat(operationName, params).pipe(hide()); + }, + args, + signal, + messages, + }) + ); + + return executeFunctionResponse$.pipe( + catchError((error) => { + // We want to catch the error only when a promise occurs + // if it occurs in the Observable, we cannot easily recover + // from it because the function may have already emitted + // values which could lead to an invalid conversation state, + // so in that case we let the stream fail. + return of(createFunctionResponseError({ name, error })); + }), + switchMap((response) => { + if (isObservable(response)) { + return response; + } + + // is messageAdd event + if ('type' in response) { + return of(response); + } + + const encoded = encode(JSON.stringify(response.content || {})); + + const exceededTokenLimit = encoded.length >= MAX_FUNCTION_RESPONSE_TOKEN_COUNT; + + return of( + createFunctionResponseMessage({ + name, + content: exceededTokenLimit + ? { + message: + 'Function response exceeded the maximum length allowed and was truncated', + truncated: decode(take(encoded, MAX_FUNCTION_RESPONSE_TOKEN_COUNT)), + } + : response.content, + data: response.data, + }) + ); + }) + ); + }); +} + +function getFunctionDefinitions({ + functionClient, + functionLimitExceeded, +}: { + functionClient: ChatFunctionClient; + functionLimitExceeded: boolean; +}) { + const systemFunctions = functionLimitExceeded + ? [] + : functionClient + .getFunctions() + .map((fn) => fn.definition) + .filter( + (def) => + !def.visibility || + [FunctionVisibility.AssistantOnly, FunctionVisibility.All].includes(def.visibility) + ); + + const actions = functionLimitExceeded ? [] : functionClient.getActions(); + + const allDefinitions = systemFunctions + .concat(actions) + .map((definition) => pick(definition, 'name', 'description', 'parameters')); + + return allDefinitions; +} + +export function continueConversation({ + messages: initialMessages, + functionClient, + chat, + signal, + functionCallsLeft, + requestInstructions, + knowledgeBaseInstructions, +}: { + messages: Message[]; + functionClient: ChatFunctionClient; + chat: ChatFunctionWithoutConnector; + signal: AbortSignal; + functionCallsLeft: number; + requestInstructions: Array; + knowledgeBaseInstructions: UserInstruction[]; +}): Observable { + let nextFunctionCallsLeft = functionCallsLeft; + + const definitions = getFunctionDefinitions({ + functionLimitExceeded: functionCallsLeft <= 0, + functionClient, + }); + + const messagesWithUpdatedSystemMessage = replaceSystemMessage( + getSystemMessageFromInstructions({ + registeredInstructions: functionClient.getInstructions(), + knowledgeBaseInstructions, + requestInstructions, + availableFunctionNames: definitions.map((def) => def.name), + }), + initialMessages + ); + + const lastMessage = + messagesWithUpdatedSystemMessage[messagesWithUpdatedSystemMessage.length - 1].message; + + const isUserMessage = lastMessage.role === MessageRole.User; + + return executeNextStep().pipe(handleEvents()); + + function executeNextStep() { + if (isUserMessage) { + const operationName = + lastMessage.name && lastMessage.name !== 'context' + ? `function_response ${lastMessage.name}` + : 'user_message'; + + return chat(operationName, { + messages: messagesWithUpdatedSystemMessage, + functions: definitions, + }).pipe(emitWithConcatenatedMessage()); + } + + const functionCallName = lastMessage.function_call?.name; + + if (!functionCallName) { + // reply from the LLM without a function request, + // so we can close the stream and wait for input from the user + return EMPTY; + } + + // we know we are executing a function here, so we can already + // subtract one, and reference the old count for if clauses + const currentFunctionCallsLeft = nextFunctionCallsLeft; + + nextFunctionCallsLeft--; + + const isAction = functionCallName && functionClient.hasAction(functionCallName); + + if (currentFunctionCallsLeft === 0) { + // create a function call response error so the LLM knows it needs to stop calling functions + return of( + createFunctionResponseError({ + name: functionCallName, + error: createFunctionLimitExceededError(), + }) + ); + } + + if (currentFunctionCallsLeft < 0) { + // LLM tried calling it anyway, throw an error + return throwError(() => createFunctionLimitExceededError()); + } + + // if it's an action, we close the stream and wait for the action response + // from the client/browser + if (isAction) { + try { + functionClient.validate( + functionCallName, + JSON.parse(lastMessage.function_call!.arguments || '{}') + ); + } catch (error) { + // return a function response error for the LLM to handle + return of( + createFunctionResponseError({ + name: functionCallName, + error, + }) + ); + } + + return EMPTY; + } + + if (!functionClient.hasFunction(functionCallName)) { + // tell the LLM the function was not found + return of( + createFunctionResponseError({ + name: functionCallName, + error: createFunctionNotFoundError(functionCallName), + }) + ); + } + + return executeFunctionAndCatchError({ + name: functionCallName, + args: lastMessage.function_call!.arguments, + chat, + functionClient, + messages: messagesWithUpdatedSystemMessage, + signal, + }); + } + + function handleEvents(): OperatorFunction { + return (events$) => { + const shared$ = events$.pipe(shareReplay()); + + return concat( + shared$, + shared$.pipe( + withoutTokenCountEvents(), + extractMessages(), + switchMap((extractedMessages) => { + if (!extractedMessages.length) { + return EMPTY; + } + return continueConversation({ + messages: messagesWithUpdatedSystemMessage.concat(extractedMessages), + chat, + functionCallsLeft: nextFunctionCallsLeft, + functionClient, + signal, + knowledgeBaseInstructions, + requestInstructions, + }); + }) + ) + ); + }; + } +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/debug.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/debug.ts new file mode 100644 index 0000000000000..4c097bcc28c1f --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/debug.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { inspect } from 'util'; +import { dematerialize, materialize, OperatorFunction, tap } from 'rxjs'; + +export function debug(prefix: string): OperatorFunction { + return (source$) => { + return source$.pipe( + materialize(), + tap((event) => { + // eslint-disable-next-line no-console + console.log(prefix + ':\n' + inspect(event, { depth: 10 })); + }), + dematerialize() + ); + }; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_messages.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_messages.ts new file mode 100644 index 0000000000000..97c12ae9f7cbb --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_messages.ts @@ -0,0 +1,24 @@ +/* + * 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 { filter, last, map, OperatorFunction, toArray } from 'rxjs'; +import { Message, MessageAddEvent, StreamingChatResponseEventType } from '../../../../common'; +import type { MessageOrChatEvent } from '../../../../common/conversation_complete'; + +export function extractMessages(): OperatorFunction { + return (source$) => { + return source$.pipe( + filter( + (event): event is MessageAddEvent => + event.type === StreamingChatResponseEventType.MessageAdd + ), + map((event) => event.message), + toArray(), + last() + ); + }; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_token_count.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_token_count.ts new file mode 100644 index 0000000000000..0d11db24732f3 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/extract_token_count.ts @@ -0,0 +1,36 @@ +/* + * 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 { filter, OperatorFunction, scan } from 'rxjs'; +import { + StreamingChatResponseEvent, + StreamingChatResponseEventType, + TokenCountEvent, +} from '../../../../common/conversation_complete'; + +export function extractTokenCount(): OperatorFunction< + StreamingChatResponseEvent, + TokenCountEvent['tokens'] +> { + return (events$) => { + return events$.pipe( + filter( + (event): event is TokenCountEvent => + event.type === StreamingChatResponseEventType.TokenCount + ), + scan( + (acc, event) => { + acc.completion += event.tokens.completion; + acc.prompt += event.tokens.prompt; + acc.total += event.tokens.total; + return acc; + }, + { completion: 0, prompt: 0, total: 0 } + ) + ); + }; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts new file mode 100644 index 0000000000000..f35e0716f1051 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts @@ -0,0 +1,105 @@ +/* + * 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 { catchError, map, Observable, of, tap } from 'rxjs'; +import { Logger } from '@kbn/logging'; +import type { ObservabilityAIAssistantClient } from '..'; +import { Message, MessageRole } from '../../../../common'; +import { concatenateChatCompletionChunks } from '../../../../common/utils/concatenate_chat_completion_chunks'; +import { hideTokenCountEvents } from './hide_token_count_events'; +import { ChatEvent, TokenCountEvent } from '../../../../common/conversation_complete'; + +type ChatFunctionWithoutConnectorAndTokenCount = ( + name: string, + params: Omit< + Parameters[1], + 'connectorId' | 'signal' | 'simulateFunctionCalling' + > +) => Observable; + +export function getGeneratedTitle({ + responseLanguage, + messages, + chat, + logger, +}: { + responseLanguage?: string; + messages: Message[]; + chat: ChatFunctionWithoutConnectorAndTokenCount; + logger: Logger; +}): Observable { + return hideTokenCountEvents((hide) => + chat('generate_title', { + messages: [ + { + '@timestamp': new Date().toString(), + message: { + role: MessageRole.System, + content: `You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you. Please create the title in ${responseLanguage}.`, + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.User, + content: messages.slice(1).reduce((acc, curr) => { + return `${acc} ${curr.message.role}: ${curr.message.content}`; + }, 'Generate a title, using the title_conversation_function, based on the following conversation:\n\n'), + }, + }, + ], + functions: [ + { + name: 'title_conversation', + description: + 'Use this function to title the conversation. Do not wrap the title in quotes', + parameters: { + type: 'object', + properties: { + title: { + type: 'string', + }, + }, + required: ['title'], + }, + }, + ], + functionCall: 'title_conversation', + }).pipe( + hide(), + concatenateChatCompletionChunks(), + map((concatenatedMessage) => { + const input = + (concatenatedMessage.message.function_call.name + ? JSON.parse(concatenatedMessage.message.function_call.arguments).title + : concatenatedMessage.message?.content) || ''; + + // This regular expression captures a string enclosed in single or double quotes. + // It extracts the string content without the quotes. + // Example matches: + // - "Hello, World!" => Captures: Hello, World! + // - 'Another Example' => Captures: Another Example + // - JustTextWithoutQuotes => Captures: JustTextWithoutQuotes + const match = input.match(/^["']?([^"']+)["']?$/); + const title = match ? match[1] : input; + return title; + }), + tap((event) => { + if (typeof event === 'string') { + logger.debug(`Generated title: ${event}`); + } + }) + ) + ).pipe( + catchError((error) => { + logger.error(`Error generating title`); + logger.error(error); + // TODO: i18n + return of('New conversation'); + }) + ); +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/hide_token_count_events.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/hide_token_count_events.ts new file mode 100644 index 0000000000000..7aabb1448382f --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/hide_token_count_events.ts @@ -0,0 +1,38 @@ +/* + * 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 { merge, Observable, partition } from 'rxjs'; +import type { StreamingChatResponseEvent } from '../../../../common'; +import { + StreamingChatResponseEventType, + TokenCountEvent, +} from '../../../../common/conversation_complete'; + +type Hide = () => ( + source$: Observable +) => Observable>; + +export function hideTokenCountEvents( + cb: (hide: Hide) => Observable> +): Observable { + // `hide` can be called multiple times, so we keep track of each invocation + const allInterceptors: Array> = []; + + const hide: Hide = () => (source$) => { + const [tokenCountEvents$, otherEvents$] = partition( + source$, + (value): value is TokenCountEvent => value.type === StreamingChatResponseEventType.TokenCount + ); + + allInterceptors.push(tokenCountEvents$); + + return otherEvents$; + }; + + // combine the two observables again + return merge(cb(hide), ...allInterceptors); +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/instrument_and_count_tokens.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/instrument_and_count_tokens.ts new file mode 100644 index 0000000000000..094b2606ae533 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/instrument_and_count_tokens.ts @@ -0,0 +1,71 @@ +/* + * 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 apm from 'elastic-apm-node'; +import { + catchError, + ignoreElements, + merge, + OperatorFunction, + shareReplay, + tap, + last, + throwError, + finalize, +} from 'rxjs'; +import type { StreamingChatResponseEvent } from '../../../../common/conversation_complete'; +import { extractTokenCount } from './extract_token_count'; + +export function instrumentAndCountTokens( + name: string +): OperatorFunction { + return (source$) => { + const span = apm.startSpan(name); + + if (!span) { + return source$; + } + span?.addLabels({ + plugin: 'observability_ai_assistant', + }); + + const shared$ = source$.pipe(shareReplay()); + + let tokenCount = { + prompt: 0, + completion: 0, + total: 0, + }; + + return merge( + shared$, + shared$.pipe( + extractTokenCount(), + tap((nextTokenCount) => { + tokenCount = nextTokenCount; + }), + last(), + tap(() => { + span?.setOutcome('success'); + }), + catchError((error) => { + span?.setOutcome('failure'); + return throwError(() => error); + }), + finalize(() => { + span?.addLabels({ + tokenCountPrompt: tokenCount.prompt, + tokenCountCompletion: tokenCount.completion, + tokenCountTotal: tokenCount.total, + }); + span?.end(); + }), + ignoreElements() + ) + ); + }; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts index 241ecd1350c68..00ca82521875c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts @@ -7,7 +7,7 @@ import type { FromSchema } from 'json-schema-to-ts'; import { Observable } from 'rxjs'; -import { ChatCompletionChunkEvent } from '../../common/conversation_complete'; +import { ChatCompletionChunkEvent, ChatEvent } from '../../common/conversation_complete'; import type { CompatibleJSONSchema, FunctionDefinition, @@ -27,17 +27,33 @@ export type RespondFunctionResources = Pick< 'context' | 'logger' | 'plugins' | 'request' >; -export type ChatFn = ( - ...args: Parameters -) => Promise>; +export type ChatFunction = ( + name: string, + params: Parameters[1] +) => Observable; + +export type ChatFunctionWithoutConnector = ( + name: string, + params: Omit< + Parameters[1], + 'connectorId' | 'simulateFunctionCalling' | 'signal' + > +) => Observable; + +export type FunctionCallChatFunction = ( + name: string, + params: Omit< + Parameters[1], + 'connectorId' | 'simulateFunctionCalling' + > +) => Observable; type RespondFunction = ( options: { arguments: TArguments; messages: Message[]; - connectorId: string; screenContexts: ObservabilityAIAssistantScreenContextRequest[]; - chat: ChatFn; + chat: FunctionCallChatFunction; }, signal: AbortSignal ) => Promise; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/catch_function_limit_exceeded_error.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/catch_function_limit_exceeded_error.ts index 25eecc7e7723e..01c9713f0f8e6 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/catch_function_limit_exceeded_error.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/catch_function_limit_exceeded_error.ts @@ -9,16 +9,15 @@ import { i18n } from '@kbn/i18n'; import { catchError, filter, of, OperatorFunction, shareReplay, throwError } from 'rxjs'; import { ChatCompletionChunkEvent, - MessageAddEvent, MessageRole, StreamingChatResponseEventType, } from '../../../common'; -import { isFunctionNotFoundError } from '../../../common/conversation_complete'; +import { isFunctionNotFoundError, MessageOrChatEvent } from '../../../common/conversation_complete'; import { emitWithConcatenatedMessage } from '../../../common/utils/emit_with_concatenated_message'; export function catchFunctionLimitExceededError(): OperatorFunction< - ChatCompletionChunkEvent | MessageAddEvent, - ChatCompletionChunkEvent | MessageAddEvent + MessageOrChatEvent, + MessageOrChatEvent > { return (source$) => { const shared$ = source$.pipe(shareReplay()); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/observable_into_stream.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/observable_into_stream.ts index f6fe506367f2f..3ca09acde2b6f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/observable_into_stream.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/observable_into_stream.ts @@ -13,11 +13,10 @@ import { isChatCompletionError, StreamingChatResponseEventType, StreamingChatResponseEventWithoutError, - TokenCountEvent, } from '../../../common/conversation_complete'; export function observableIntoStream( - source: Observable + source: Observable ) { const stream = new PassThrough(); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/reject_token_count_events.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/reject_token_count_events.ts deleted file mode 100644 index b8e563495d1d7..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/reject_token_count_events.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { filter, Observable } from 'rxjs'; -import { - ChatCompletionChunkEvent, - StreamingChatResponseEventType, - TokenCountEvent, -} from '../../../common/conversation_complete'; - -export function rejectTokenCountEvents() { - return ( - source: Observable - ): Observable> => { - return source.pipe( - filter( - (event): event is Exclude => - event.type !== StreamingChatResponseEventType.TokenCount - ) - ); - }; -} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/with_assistant_span.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/with_assistant_span.ts new file mode 100644 index 0000000000000..44494e978d804 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/util/with_assistant_span.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { withSpan, SpanOptions, parseSpanOptions } from '@kbn/apm-utils'; + +export function withAssistantSpan( + optionsOrName: SpanOptions | string, + cb: () => Promise +): Promise { + const options = parseSpanOptions(optionsOrName); + + const optionsWithDefaults = { + ...(options.intercept ? {} : { type: 'plugin:observability_ai_assistant' }), + ...options, + labels: { + plugin: 'observability_ai_assistant', + ...options.labels, + }, + }; + + return withSpan(optionsWithDefaults, cb); +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json index eee8ea0d56911..cc66498fa5d4e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json @@ -48,6 +48,7 @@ "@kbn/cloud-plugin", "@kbn/serverless", "@kbn/triggers-actions-ui-plugin", + "@kbn/apm-utils" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts index 2cf8600d9db2f..ab0964fdc6216 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts @@ -142,7 +142,7 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra description: `This function generates, executes and/or visualizes a query based on the user's request. It also explains how ES|QL works and how to convert queries from one language to another. Make sure you call one of the get_dataset functions first if you need index or field names. This function takes no input.`, visibility: FunctionVisibility.AssistantOnly, }, - async ({ messages, connectorId, chat }, signal) => { + async ({ messages, chat }, signal) => { const [systemMessage, esqlDocs] = await Promise.all([loadSystemMessage(), loadEsqlDocs()]); const withEsqlSystemMessage = (message?: string) => [ @@ -155,7 +155,6 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra const source$ = ( await chat('classify_esql', { - connectorId, messages: withEsqlSystemMessage().concat({ '@timestamp': new Date().toISOString(), message: { @@ -382,7 +381,6 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra }, }, ], - connectorId, signal, functions: functions.getActions(), }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts index 1a7d64c0d324f..1523ca510238a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts @@ -27,25 +27,22 @@ export function registerVisualizeESQLFunction({ functions, resources, }: FunctionRegistrationParameters) { - functions.registerFunction( - visualizeESQLFunction, - async ({ arguments: { query, intention }, connectorId, messages }, signal) => { - const { columns, errorMessages } = await validateEsqlQuery({ - query, - client: (await resources.context.core).elasticsearch.client.asCurrentUser, - }); + functions.registerFunction(visualizeESQLFunction, async ({ arguments: { query, intention } }) => { + const { columns, errorMessages } = await validateEsqlQuery({ + query, + client: (await resources.context.core).elasticsearch.client.asCurrentUser, + }); - const message = getMessageForLLM(intention, query, Boolean(errorMessages?.length)); + const message = getMessageForLLM(intention, query, Boolean(errorMessages?.length)); - return { - data: { - columns, - }, - content: { - message, - errorMessages, - }, - }; - } - ); + return { + data: { + columns, + }, + content: { + message, + errorMessages, + }, + }; + }); } diff --git a/x-pack/test/observability_ai_assistant_api_integration/tests/chat/chat.spec.ts b/x-pack/test/observability_ai_assistant_api_integration/tests/chat/chat.spec.ts index b69ef1c512fa1..a9cf749b3d761 100644 --- a/x-pack/test/observability_ai_assistant_api_integration/tests/chat/chat.spec.ts +++ b/x-pack/test/observability_ai_assistant_api_integration/tests/chat/chat.spec.ts @@ -160,6 +160,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { connectorId, functions: [], }) + .expect(200) .pipe(passThrough); let data: string = ''; @@ -188,9 +189,9 @@ export default function ApiTest({ getService }: FtrProviderContext) { await new Promise((resolve) => passThrough.on('end', () => resolve())); - const response = JSON.parse(data); + const response = JSON.parse(data.trim()); - expect(response.message).to.be( + expect(response.error.message).to.be( `Token limit reached. Token limit is 8192, but the current conversation has 11036 tokens.` ); }); From cb09b552838c0a9c9ea96603c1925b4b1bef7aa9 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 30 Apr 2024 14:26:29 +0200 Subject: [PATCH 034/104] polyfill window.matchMedia in jsdom (#181710) --- .../src/jest/setup/polyfills.jsdom.js | 24 +++++++++++++++++++ .../src/text_based_languages_editor.test.tsx | 18 +------------- .../src/utils/get_render_cell_value.test.tsx | 10 -------- .../column_headers/helpers.test.tsx | 10 -------- .../components/data_table/index.test.tsx | 9 ------- .../cases/public/common/mock/match_media.ts | 20 ---------------- .../all_cases/all_cases_list.test.tsx | 1 - .../all_cases/use_cases_columns.test.tsx | 1 - .../case_view/case_view_page.test.tsx | 1 - .../case_view/case_view_tabs.test.tsx | 1 - .../components/case_view/index.test.tsx | 1 - .../header_page/editable_title.test.tsx | 1 - .../components/header_page/index.test.tsx | 1 - .../components/header_page/title.test.tsx | 1 - .../public/components/links/index.test.tsx | 1 - .../use_push_to_service/index.test.tsx | 1 - .../public/test/test_provider.tsx | 14 ----------- .../template_clone.test.tsx | 16 ------------- .../components/charts/barchart.test.tsx | 1 - .../charts/draggable_legend.test.tsx | 1 - .../charts/draggable_legend_item.test.tsx | 1 - .../drag_and_drop/draggable_wrapper.test.tsx | 1 - .../components/draggables/index.test.tsx | 1 - .../event_details/event_details.test.tsx | 1 - .../event_fields_browser.test.tsx | 1 - .../components/events_viewer/index.test.tsx | 1 - .../filters_global/filters_global.test.tsx | 1 - .../header_page/editable_title.test.tsx | 1 - .../components/header_page/index.test.tsx | 1 - .../components/header_page/title.test.tsx | 1 - .../common/components/ml/entity.test.tsx | 1 - .../ml/score/anomaly_score.test.tsx | 1 - .../ml/score/anomaly_scores.test.tsx | 1 - .../common/components/ml/score/score.test.tsx | 1 - .../get_anomalies_host_table_columns.test.tsx | 1 - ...t_anomalies_network_table_columns.test.tsx | 1 - .../get_anomalies_table_columns.test.tsx | 1 - .../get_anomalies_user_table_columns.test.tsx | 1 - .../common/components/tables/helpers.test.tsx | 1 - .../common/components/top_n/index.test.tsx | 1 - .../common/components/top_n/top_n.test.tsx | 1 - .../public/common/mock/match_media.ts | 22 ----------------- .../middlware_local_storage.test.ts | 1 - .../alerts_table/alerts_grouping.test.tsx | 1 - .../detection_engine.test.tsx | 1 - .../authentications_host_table.test.tsx | 1 - .../authentications_user_table.test.tsx | 1 - .../components/hosts_table/index.test.tsx | 1 - .../uncommon_process_table/index.test.tsx | 1 - .../hosts/pages/details/details_tabs.test.tsx | 1 - .../public/explore/hosts/pages/hosts.test.tsx | 1 - .../network/components/details/index.test.tsx | 1 - .../components/direction/direction.test.tsx | 1 - .../embeddables/embedded_map.test.tsx | 1 - .../line_tool_tip_content.test.tsx | 1 - .../map_tool_tip/map_tool_tip.test.tsx | 1 - .../point_tool_tip_content.test.tsx | 1 - .../index.test.tsx | 1 - .../network/components/ip/index.test.tsx | 1 - .../components/kpi_network/index.test.tsx | 1 - .../network_dns_table/index.test.tsx | 1 - .../network_http_table/index.test.tsx | 1 - .../index.test.tsx | 1 - .../network_top_n_flow_table/index.test.tsx | 1 - .../network/components/port/index.test.tsx | 1 - .../source_destination/index.test.tsx | 1 - .../source_destination_ip.test.tsx | 1 - .../components/tls_table/index.test.tsx | 1 - .../components/users_table/index.test.tsx | 1 - .../network/pages/details/index.test.tsx | 2 -- .../explore/network/pages/network.test.tsx | 1 - .../users/components/all_users/index.test.tsx | 1 - .../explore/users/pages/users_tabs.test.tsx | 1 - .../pages/endpoint_hosts/view/index.test.tsx | 1 - .../pages/integration_tests/index.test.tsx | 1 - .../components/event_counts/index.test.tsx | 1 - .../endpoint_overview/index.test.tsx | 1 - .../components/host_overview/index.test.tsx | 1 - .../components/overview_host/index.test.tsx | 1 - .../overview_network/index.test.tsx | 1 - .../components/user_overview/index.test.tsx | 1 - .../public/overview/pages/overview.test.tsx | 1 - .../certificate_fingerprint/index.test.tsx | 1 - .../components/duration/index.test.tsx | 1 - .../field_renderers/field_renderers.test.tsx | 1 - .../components/ja3_fingerprint/index.test.tsx | 1 - .../components/netflow/index.test.tsx | 1 - .../components/open_timeline/index.test.tsx | 1 - .../open_timeline/open_timeline.test.tsx | 1 - .../open_timeline_modal_body.test.tsx | 1 - .../timelines_table/actions_columns.test.tsx | 2 -- .../timelines_table/common_columns.test.tsx | 1 - .../timelines_table/extended_columns.test.tsx | 1 - .../icon_header_columns.test.tsx | 1 - .../timelines_table/index.test.tsx | 1 - .../event_details/flyout/footer.test.tsx | 1 - .../side_panel/event_details/index.test.tsx | 1 - .../host_details/expandable_host.test.tsx | 1 - .../components/side_panel/index.test.tsx | 1 - .../user_details/expandable_user.test.tsx | 1 - .../body/column_headers/helpers.test.ts | 1 - .../body/column_headers/index.test.tsx | 1 - .../body/data_driven_columns/index.test.tsx | 1 - .../components/timeline/body/index.test.tsx | 1 - .../timeline/body/renderers/args.test.tsx | 1 - .../renderers/auditd/generic_details.test.tsx | 1 - .../auditd/generic_file_details.test.tsx | 1 - .../primary_secondary_user_info.test.tsx | 1 - .../session_user_host_working_dir.test.tsx | 1 - .../body/renderers/bytes/index.test.tsx | 1 - .../dns/dns_request_event_details.test.tsx | 1 - .../dns_request_event_details_line.test.tsx | 1 - .../renderers/empty_column_renderer.test.tsx | 1 - .../endgame_security_event_details.test.tsx | 1 - ...dgame_security_event_details_line.test.tsx | 1 - .../renderers/exit_code_draggable.test.tsx | 1 - .../body/renderers/file_draggable.test.tsx | 1 - .../body/renderers/file_hash.test.tsx | 1 - .../body/renderers/formatted_field.test.tsx | 1 - .../renderers/get_column_renderer.test.tsx | 1 - .../body/renderers/get_row_renderer.test.tsx | 1 - .../body/renderers/host_working_dir.test.tsx | 1 - .../netflow/netflow_row_renderer.test.tsx | 1 - .../parent_process_draggable.test.tsx | 1 - .../renderers/plain_column_renderer.test.tsx | 1 - .../body/renderers/process_draggable.test.tsx | 1 - .../body/renderers/process_hash.test.tsx | 1 - .../registry/registry_event_details.test.tsx | 1 - .../registry_event_details_line.test.tsx | 1 - .../suricata/suricata_details.test.tsx | 1 - .../suricata/suricata_row_renderer.test.tsx | 1 - .../suricata/suricata_signature.test.tsx | 1 - .../body/renderers/system/auth_ssh.test.tsx | 1 - .../renderers/system/generic_details.test.tsx | 1 - .../system/generic_file_details.test.tsx | 1 - .../body/renderers/system/package.test.tsx | 1 - .../renderers/user_host_working_dir.test.tsx | 1 - .../body/renderers/zeek/zeek_details.test.tsx | 1 - .../renderers/zeek/zeek_row_renderer.test.tsx | 1 - .../renderers/zeek/zeek_signature.test.tsx | 1 - .../components/timeline/index.test.tsx | 1 - .../timeline/tabs/eql/index.test.tsx | 1 - .../timeline/tabs/pinned/index.test.tsx | 1 - .../timeline/tabs/query/index.test.tsx | 1 - .../components/session_view/index.test.tsx | 18 -------------- .../components/tty_player/hooks.test.tsx | 16 ------------- .../components/tty_player/index.test.tsx | 18 -------------- 147 files changed, 25 insertions(+), 307 deletions(-) delete mode 100644 x-pack/plugins/cases/public/common/mock/match_media.ts delete mode 100644 x-pack/plugins/security_solution/public/common/mock/match_media.ts diff --git a/packages/kbn-test/src/jest/setup/polyfills.jsdom.js b/packages/kbn-test/src/jest/setup/polyfills.jsdom.js index dbe4213ca83f7..0867862b2d4ca 100644 --- a/packages/kbn-test/src/jest/setup/polyfills.jsdom.js +++ b/packages/kbn-test/src/jest/setup/polyfills.jsdom.js @@ -46,4 +46,28 @@ if (!global.hasOwnProperty('Worker')) { } global.Worker = Worker; + + // Mocking matchMedia to resolve TypeError: window.matchMedia is not a function + // For more info, see https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom + if (!global.hasOwnProperty('matchMedia')) { + Object.defineProperty(global, 'matchMedia', { + writable: true, + // eslint-disable-next-line no-undef + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + // eslint-disable-next-line no-undef + addListener: jest.fn(), // deprecated + // eslint-disable-next-line no-undef + removeListener: jest.fn(), // deprecated + // eslint-disable-next-line no-undef + addEventListener: jest.fn(), + // eslint-disable-next-line no-undef + removeEventListener: jest.fn(), + // eslint-disable-next-line no-undef + dispatchEvent: jest.fn(), + })), + }); + } } diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx index 6aae293e9ae9b..3744e4acb1984 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx @@ -59,23 +59,7 @@ describe('TextBasedLanguagesEditor', () => { ); } let props: TextBasedLanguagesEditorProps; - beforeAll(() => { - // Mocking matchMedia to resolve TypeError: window.matchMedia is not a function - // For more info, see https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom - Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), - }); - }); + beforeEach(() => { props = { query: { esql: 'from test' }, diff --git a/packages/kbn-unified-data-table/src/utils/get_render_cell_value.test.tsx b/packages/kbn-unified-data-table/src/utils/get_render_cell_value.test.tsx index 4b00a85a29f39..8d18c7d454db7 100644 --- a/packages/kbn-unified-data-table/src/utils/get_render_cell_value.test.tsx +++ b/packages/kbn-unified-data-table/src/utils/get_render_cell_value.test.tsx @@ -38,16 +38,6 @@ jest.mock('@kbn/code-editor', () => { }; }); -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), - removeListener: jest.fn(), - }; -}); - const mockServices = { settings: { client: { diff --git a/x-pack/packages/security-solution/data_table/components/data_table/column_headers/helpers.test.tsx b/x-pack/packages/security-solution/data_table/components/data_table/column_headers/helpers.test.tsx index b6a4ae9cd0c67..dfb495201f6d1 100644 --- a/x-pack/packages/security-solution/data_table/components/data_table/column_headers/helpers.test.tsx +++ b/x-pack/packages/security-solution/data_table/components/data_table/column_headers/helpers.test.tsx @@ -23,16 +23,6 @@ import type { ColumnHeaderOptions } from '../../../common/types'; import { defaultHeaders } from '../../../store/data_table/defaults'; import { mockBrowserFields } from '../../../mock/mock_source'; -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), - removeListener: jest.fn(), - }; -}); - describe('helpers', () => { describe('getColumnWidthFromType', () => { test('it returns the expected width for a non-date column', () => { diff --git a/x-pack/packages/security-solution/data_table/components/data_table/index.test.tsx b/x-pack/packages/security-solution/data_table/components/data_table/index.test.tsx index c9cf666cc053a..b410958343167 100644 --- a/x-pack/packages/security-solution/data_table/components/data_table/index.test.tsx +++ b/x-pack/packages/security-solution/data_table/components/data_table/index.test.tsx @@ -48,15 +48,6 @@ jest.mock('../../hooks/use_selector', () => ({ useDeepEqualSelector: () => mockGlobalState.dataTable.tableById['table-test'], })); -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), - removeListener: jest.fn(), - }; -}); const dataViewId = 'security-solution-default'; export const TestCellRenderer: React.FC = ({ columnId, data }) => ( diff --git a/x-pack/plugins/cases/public/common/mock/match_media.ts b/x-pack/plugins/cases/public/common/mock/match_media.ts deleted file mode 100644 index eab1b669d7013..0000000000000 --- a/x-pack/plugins/cases/public/common/mock/match_media.ts +++ /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. - */ - -// TODO(jbudz): should be removed when upgrading to TS@4.8 -// this is a skip for the errors created when typechecking with isolatedModules -export {}; - -window.matchMedia = jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), -})); diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx index 5a34be12232d3..56fc3a68f4877 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx @@ -12,7 +12,6 @@ import { renderHook } from '@testing-library/react-hooks'; import userEvent from '@testing-library/user-event'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; -import '../../common/mock/match_media'; import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer, diff --git a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx index 5ad01f44f6a57..6cb7827a580c4 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; -import '../../common/mock/match_media'; import type { GetCasesColumn } from './use_cases_columns'; import { ExternalServiceColumn, useCasesColumns } from './use_cases_columns'; import { useGetCasesMockState } from '../../containers/mock'; diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx index 1d76033295376..42cd932996dc2 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { waitFor, screen } from '@testing-library/react'; import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer } from '../../common/mock'; -import '../../common/mock/match_media'; import { useUrlParams } from '../../common/navigation/hooks'; import { CaseViewPage } from './case_view_page'; import { caseData, caseViewProps } from './mocks'; diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_tabs.test.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_tabs.test.tsx index a6c2be1884cd2..4ee423892ebb1 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_tabs.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_tabs.test.tsx @@ -14,7 +14,6 @@ import type { UseGetCase } from '../../containers/use_get_case'; import type { CaseViewTabsProps } from './case_view_tabs'; import { CASE_VIEW_PAGE_TABS } from '../../../common/types'; -import '../../common/mock/match_media'; import { createAppMockRenderer } from '../../common/mock'; import { useCaseViewNavigation } from '../../common/navigation/hooks'; import { useGetCase } from '../../containers/use_get_case'; diff --git a/x-pack/plugins/cases/public/components/case_view/index.test.tsx b/x-pack/plugins/cases/public/components/case_view/index.test.tsx index 13524989bc7b8..849a41d4bb437 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.test.tsx @@ -14,7 +14,6 @@ import React from 'react'; -import '../../common/mock/match_media'; import type { CaseViewProps } from './types'; import { connectorsMock } from '../../containers/mock'; import type { SpacesApi } from '@kbn/spaces-plugin/public'; diff --git a/x-pack/plugins/cases/public/components/header_page/editable_title.test.tsx b/x-pack/plugins/cases/public/components/header_page/editable_title.test.tsx index 9f75a94274aaf..50c672564b9d9 100644 --- a/x-pack/plugins/cases/public/components/header_page/editable_title.test.tsx +++ b/x-pack/plugins/cases/public/components/header_page/editable_title.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../common/mock/match_media'; import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer, readCasesPermissions, TestProviders } from '../../common/mock'; import type { EditableTitleProps } from './editable_title'; diff --git a/x-pack/plugins/cases/public/components/header_page/index.test.tsx b/x-pack/plugins/cases/public/components/header_page/index.test.tsx index ff221614a1792..c2a9aa9c99d97 100644 --- a/x-pack/plugins/cases/public/components/header_page/index.test.tsx +++ b/x-pack/plugins/cases/public/components/header_page/index.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../common/mock/match_media'; import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer, TestProviders } from '../../common/mock'; import { HeaderPage } from '.'; diff --git a/x-pack/plugins/cases/public/components/header_page/title.test.tsx b/x-pack/plugins/cases/public/components/header_page/title.test.tsx index bd26b37956e65..c3ca0ca07055c 100644 --- a/x-pack/plugins/cases/public/components/header_page/title.test.tsx +++ b/x-pack/plugins/cases/public/components/header_page/title.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import '../../common/mock/match_media'; import { Title } from './title'; describe('Title', () => { diff --git a/x-pack/plugins/cases/public/components/links/index.test.tsx b/x-pack/plugins/cases/public/components/links/index.test.tsx index 81fd9217f19de..4d962197951a9 100644 --- a/x-pack/plugins/cases/public/components/links/index.test.tsx +++ b/x-pack/plugins/cases/public/components/links/index.test.tsx @@ -12,7 +12,6 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { EuiText } from '@elastic/eui'; -import '../../common/mock/match_media'; import type { ConfigureCaseButtonProps, CaseDetailsLinkProps } from '.'; import { ConfigureCaseButton, CaseDetailsLink } from '.'; import { TestProviders } from '../../common/mock'; diff --git a/x-pack/plugins/cases/public/components/use_push_to_service/index.test.tsx b/x-pack/plugins/cases/public/components/use_push_to_service/index.test.tsx index 7b2a30df15171..bf607c7659333 100644 --- a/x-pack/plugins/cases/public/components/use_push_to_service/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_push_to_service/index.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; -import '../../common/mock/match_media'; import type { ReturnUsePushToService, UsePushToService } from '.'; import { usePushToService } from '.'; import { noPushCasesPermissions, readCasesPermissions, TestProviders } from '../../common/mock'; diff --git a/x-pack/plugins/cloud_defend/public/test/test_provider.tsx b/x-pack/plugins/cloud_defend/public/test/test_provider.tsx index cfd74d118ebe5..9b61b65f30a87 100755 --- a/x-pack/plugins/cloud_defend/public/test/test_provider.tsx +++ b/x-pack/plugins/cloud_defend/public/test/test_provider.tsx @@ -21,20 +21,6 @@ import '@kbn/code-editor-mock/jest_helper'; // @ts-ignore-next window.Worker = Worker; -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // Deprecated - removeListener: jest.fn(), // Deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), -}); - interface CloudDefendAppDeps { core: CoreStart; deps: CloudDefendPluginStartDeps; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx index 8523ebda8b32d..faf1bd31044cd 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx @@ -50,22 +50,6 @@ describe('', () => { httpRequestsMockHelpers.setLoadTelemetryResponse({}); httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); httpRequestsMockHelpers.setLoadTemplateResponse(templateToClone.name, templateToClone); - - // Mocking matchMedia to resolve TypeError: window.matchMedia is not a function - // For more info, see https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom - Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), - }); }); afterAll(() => { diff --git a/x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx index 38d3aeb37bac9..7a5eb94d56249 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx @@ -13,7 +13,6 @@ import React from 'react'; import { escapeDataProviderId } from '../drag_and_drop/helpers'; import { TestProviders } from '../../mock'; -import '../../mock/match_media'; import '../../mock/react_beautiful_dnd'; import { BarChartBaseComponent, BarChartComponent } from './barchart'; diff --git a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx index 9b0394696b1f5..be062ea0b1c33 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx @@ -9,7 +9,6 @@ import type { ReactWrapper } from 'enzyme'; import { mount } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import '../../mock/react_beautiful_dnd'; import { TestProviders } from '../../mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx index aa1d1e57760f1..edee3083fde8c 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx @@ -9,7 +9,6 @@ import type { ReactWrapper } from 'enzyme'; import { mount } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import '../../mock/react_beautiful_dnd'; import { TestProviders } from '../../mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index 2bc0ba7f1ac35..dca5ac2c063b4 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -10,7 +10,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import type { DraggableStateSnapshot, DraggingStyle } from '@hello-pangea/dnd'; -import '../../mock/match_media'; import { mockBrowserFields } from '../../containers/source/mock'; import { TestProviders } from '../../mock'; import { mockDataProviders } from '../../../timelines/components/timeline/data_providers/mock/mock_data_providers'; diff --git a/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx index e1f052dbf83b0..d1c90890d7d81 100644 --- a/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx @@ -11,7 +11,6 @@ import { EuiToolTip } from '@elastic/eui'; import { DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY } from '../drag_and_drop/translations'; import { TestProviders } from '../../mock'; -import '../../mock/match_media'; import { getEmptyString } from '../empty_value'; import { useMountAppended } from '../../utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx index 2718c3adf2012..f03e204301d87 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx @@ -10,7 +10,6 @@ import { mount } from 'enzyme'; import type { ReactWrapper } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import '../../mock/react_beautiful_dnd'; import { mockDetailItemData, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx index 570029e1c3c0b..433cf98d8fa97 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../mock/match_media'; import { mockDetailItemData, mockDetailItemDataId } from '../../mock/mock_detail_item'; import { TestProviders } from '../../mock/test_providers'; import { EventFieldsBrowser } from './event_fields_browser'; diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx index 903f1f7c548c9..aa3873e5e69b8 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import useResizeObserver from 'use-resize-observer/polyfilled'; -import '../../mock/match_media'; import { render } from '@testing-library/react'; import { TestProviders } from '../../mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx index f903e7e492f07..ce628b3460f41 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx @@ -9,7 +9,6 @@ import type { ReactWrapper } from 'enzyme'; import { mount, shallow } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import { FiltersGlobal } from './filters_global'; import { TestProviders } from '../../mock/test_providers'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx index 642d09bfde11d..59b40f3f0cb25 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import { TestProviders } from '../../mock'; import { EditableTitle } from './editable_title'; import { useMountAppended } from '../../utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx index 762ce80c7c6a5..4e95954e70dee 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx @@ -9,7 +9,6 @@ import { euiDarkVars } from '@kbn/ui-theme'; import { shallow } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import { TestProviders } from '../../mock'; import { HeaderPage } from '.'; import { useMountAppended } from '../../utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx index d2f030fb15ba3..edc82f99e3a6a 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../mock/match_media'; import { TestProviders } from '../../mock'; import { Title } from './title'; import { useMountAppended } from '../../utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/entity.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/entity.test.tsx index 4441e483f063b..2aea3c958bdcf 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/entity.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/entity.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import '../../mock/match_media'; import { EntityComponent } from './entity'; import { TestProviders } from '../../mock/test_providers'; import { useMountAppended } from '../../utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx index d8b43fa9a603b..ce735801eddc0 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; -import '../../../mock/match_media'; import { AnomalyScoreComponent } from './anomaly_score'; import { mockAnomalies } from '../mock'; import { TestProviders } from '../../../mock/test_providers'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx index b54ec85bab0e4..2c105840b2a0b 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; -import '../../../mock/match_media'; import { AnomalyScoresComponent, createJobKey } from './anomaly_scores'; import { mockAnomalies } from '../mock'; import { TestProviders } from '../../../mock/test_providers'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/score.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/score.test.tsx index e47d4d890e5f5..a6fdc79eef98b 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/score.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/score.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { cloneDeep } from 'lodash/fp'; import { shallow } from 'enzyme'; -import '../../../mock/match_media'; import { ScoreComponent } from './score'; import { mockAnomalies } from '../mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx index d4818cc4436c3..0709a788fd117 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import '../../../mock/match_media'; import { getAnomaliesHostTableColumnsCurated } from './get_anomalies_host_table_columns'; import { HostsType } from '../../../../explore/hosts/store/model'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx index f07308a9fa6cf..f6dcdc11efe77 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import '../../../mock/match_media'; import { getAnomaliesNetworkTableColumnsCurated } from './get_anomalies_network_table_columns'; import { NetworkType } from '../../../../explore/network/store/model'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_table_columns.test.tsx index 0e8fbb0794b7c..c25a07fc76a38 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_table_columns.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import '../../../mock/match_media'; import * as i18n from './translations'; import type { AnomaliesBy, Anomaly } from '../types'; import type { Columns } from '../../../../explore/components/paginated_table'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_user_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_user_table_columns.test.tsx index af29e63c9f264..e600df73d7766 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_user_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_user_table_columns.test.tsx @@ -6,7 +6,6 @@ */ import { UsersType } from '../../../../explore/users/store/model'; -import '../../../mock/match_media'; import { getAnomaliesUserTableColumnsCurated } from './get_anomalies_user_table_columns'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx index 2a45340253461..852bf3759fa04 100644 --- a/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import '../../mock/match_media'; import { RowItemOverflowComponent, OverflowFieldComponent, diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx index 217e0e2942d78..5e8936c1f8b44 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx @@ -9,7 +9,6 @@ import type { ReactWrapper } from 'enzyme'; import { mount } from 'enzyme'; import React from 'react'; import { waitFor } from '@testing-library/react'; -import '../../mock/match_media'; import { mockBrowserFields } from '../../containers/source/mock'; import { mockGlobalState, TestProviders, mockIndexPattern, createMockStore } from '../../mock'; import type { State } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx index d2f6efb7a5fcf..79ab897e34bfc 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx @@ -10,7 +10,6 @@ import { mount } from 'enzyme'; import React from 'react'; import { waitFor } from '@testing-library/react'; -import '../../mock/match_media'; import { TestProviders, mockIndexPattern } from '../../mock'; import { allEvents, defaultOptions } from './helpers'; diff --git a/x-pack/plugins/security_solution/public/common/mock/match_media.ts b/x-pack/plugins/security_solution/public/common/mock/match_media.ts deleted file mode 100644 index 8fca7f8ee3686..0000000000000 --- a/x-pack/plugins/security_solution/public/common/mock/match_media.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. - */ - -// TODO(jbudz): should be removed when upgrading to TS@4.8 -// this is a skip for the errors created when typechecking with isolatedModules -export {}; - -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - }; -}); diff --git a/x-pack/plugins/security_solution/public/common/store/data_table/middlware_local_storage.test.ts b/x-pack/plugins/security_solution/public/common/store/data_table/middlware_local_storage.test.ts index 0e2c9b3d12ebf..57088b9f69506 100644 --- a/x-pack/plugins/security_solution/public/common/store/data_table/middlware_local_storage.test.ts +++ b/x-pack/plugins/security_solution/public/common/store/data_table/middlware_local_storage.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import '../../mock/match_media'; import { defaultHeaders, createSecuritySolutionStorageMock, createMockStore } from '../../mock'; import { addTableInStorage } from '../../../timelines/containers/local_storage'; import { Direction } from '../../../../common/search_strategy'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx index 1153cced85ba9..d7bc936f5a06a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx @@ -10,7 +10,6 @@ import { fireEvent, render, within } from '@testing-library/react'; import type { Filter } from '@kbn/es-query'; import useResizeObserver from 'use-resize-observer/polyfilled'; -import '../../../common/mock/match_media'; import { createMockStore, mockGlobalState, TestProviders } from '../../../common/mock'; import type { AlertsTableComponentProps } from './alerts_grouping'; import { GroupedAlertsTable } from './alerts_grouping'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx index 1deb6c98096b1..2f14a455ff12b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx @@ -8,7 +8,6 @@ import React, { useEffect } from 'react'; import { render, waitFor } from '@testing-library/react'; import { useParams } from 'react-router-dom'; -import '../../../common/mock/match_media'; import { mockGlobalState, TestProviders, createMockStore } from '../../../common/mock'; import { useUserData } from '../../components/user_info'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; diff --git a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.test.tsx b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.test.tsx index 7264fe382a760..cbcf346f43bd5 100644 --- a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import '../../../common/mock/match_media'; import * as i18n from './translations'; import { AuthenticationsHostTable } from './authentications_host_table'; diff --git a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.test.tsx b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.test.tsx index c78063ebfbfc1..b70a997934b58 100644 --- a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { useAuthentications } from '../../containers/authentications'; diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.test.tsx index 866dbc95fb054..d46182ca7f4d9 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { hostsModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/uncommon_process_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/components/uncommon_process_table/index.test.tsx index 7505780da0274..5f052bef9bd03 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/uncommon_process_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/components/uncommon_process_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; -import '../../../../common/mock/match_media'; import { hostsModel } from '../../store'; import { getEmptyValue } from '../../../../common/components/empty_value'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx index 2140b6cd66375..8d89e580a97e8 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import useResizeObserver from 'use-resize-observer/polyfilled'; -import '../../../../common/mock/match_media'; import { createMockStore, mockGlobalState, diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.test.tsx index 0359fa2a4609f..2fff742738bb8 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { Router } from '@kbn/shared-ux-router'; import type { Filter } from '@kbn/es-query'; -import '../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../common/mock'; import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { inputsActions } from '../../../common/store/inputs'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/details/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/details/index.test.tsx index 32ee04c25989c..6f2c748d7f54a 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/details/index.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import type { ActionCreator } from 'typescript-fsa'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock'; import { networkModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/direction/direction.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/direction/direction.test.tsx index e44ec02298cc5..9812b87b9b526 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/direction/direction.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/direction/direction.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import '../../../../common/mock/match_media'; import { DEFAULT_ICON, EXTERNAL, diff --git a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embedded_map.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embedded_map.test.tsx index 7dc84b8ceb4a3..c25865eebd7b0 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embedded_map.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/embedded_map.test.tsx @@ -7,7 +7,6 @@ import { render, waitFor } from '@testing-library/react'; import React from 'react'; -import '../../../../common/mock/match_media'; import { TestProviders, mockGlobalState, createMockStore } from '../../../../common/mock'; import { EmbeddedMapComponent } from './embedded_map'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx index 119013a62f929..d3684d2691c98 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { LineToolTipContentComponent } from './line_tool_tip_content'; import { SUM_OF_CLIENT_BYTES, diff --git a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/map_tool_tip.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/map_tool_tip.test.tsx index 6d18f3ec624d8..fb8b0ec79b961 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/map_tool_tip.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/map_tool_tip.test.tsx @@ -7,7 +7,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { MapToolTipComponent } from './map_tool_tip'; import type { TooltipFeature } from '@kbn/maps-plugin/common'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx index 74976ca856e08..1297e88a76d19 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { getRenderedFieldValue, PointToolTipContentComponent } from './point_tool_tip_content'; import { TestProviders } from '../../../../../common/mock'; import { getEmptyStringTag } from '../../../../../common/components/empty_value'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/flow_target_select_connected/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/flow_target_select_connected/index.test.tsx index 84f256068e958..549c56dfb8ce0 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/flow_target_select_connected/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/flow_target_select_connected/index.test.tsx @@ -9,7 +9,6 @@ import { mount } from 'enzyme'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock'; import { FlowTargetSelectConnectedComponent } from '.'; import { FlowTarget } from '../../../../../common/search_strategy'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/ip/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/ip/index.test.tsx index d2246541dbb2e..b5c9afda7e3a2 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/ip/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/ip/index.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock/test_providers'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/kpi_network/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/kpi_network/index.test.tsx index b204b6102a036..28b98215235af 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/kpi_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/kpi_network/index.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { createMockStore } from '../../../../common/mock'; -import '../../../../common/mock/match_media'; import { NetworkKpiComponent } from '.'; describe('NetworkKpiComponent', () => { diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.test.tsx index b8ac590a28132..e5ff1cd743699 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { networkModel } from '../../store'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.test.tsx index 7a45999f5d05b..97faa8321bac0 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { networkModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.test.tsx index d3daacedcde18..6714edcf7c4a3 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { FlowTargetSourceDest } from '../../../../../common/search_strategy/security_solution/network'; import { mockIndexPattern, TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.test.tsx index f7f88c5ab3e47..ecc2d7a9bc0d1 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { networkModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/port/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/port/index.test.tsx index de274fca2fbb4..dcadb66c546c6 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/port/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/port/index.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock/test_providers'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/source_destination/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/source_destination/index.test.tsx index 414d35ae67748..32ceb137ef907 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/source_destination/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/source_destination/index.test.tsx @@ -12,7 +12,6 @@ import { render, screen, within } from '@testing-library/react'; import { asArrayIfExists } from '../../../../common/lib/helpers'; import { getMockNetflowData } from '../../../../common/mock'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock/test_providers'; import { ID_FIELD_NAME } from '../../../../common/components/event_details/event_id'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/source_destination/source_destination_ip.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/source_destination/source_destination_ip.test.tsx index 2f988c37a4b8f..9e26df10e22b5 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/source_destination/source_destination_ip.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/source_destination/source_destination_ip.test.tsx @@ -11,7 +11,6 @@ import { render, screen } from '@testing-library/react'; import { asArrayIfExists } from '../../../../common/lib/helpers'; import { getMockNetflowData } from '../../../../common/mock'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock/test_providers'; import { ID_FIELD_NAME } from '../../../../common/components/event_details/event_id'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.test.tsx index 0d0e77c5d4867..55666754f7788 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { networkModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.test.tsx index 3880846a9d9ab..604c3a1fa964b 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.test.tsx @@ -10,7 +10,6 @@ import { getOr } from 'lodash/fp'; import React from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import '../../../../common/mock/match_media'; import { TestProviders, createMockStore } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { networkModel } from '../../store'; diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.test.tsx b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.test.tsx index 5601aa95fe084..3f3273b0f99ef 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.test.tsx @@ -8,8 +8,6 @@ import React from 'react'; import { Router, useParams } from 'react-router-dom'; -import '../../../../common/mock/match_media'; - import { useSourcererDataView } from '../../../../common/containers/sourcerer'; import { TestProviders } from '../../../../common/mock'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/network.test.tsx b/x-pack/plugins/security_solution/public/explore/network/pages/network.test.tsx index 7ff298c95f81d..9faa3da9ba3b6 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/network.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/pages/network.test.tsx @@ -9,7 +9,6 @@ import { mount } from 'enzyme'; import React from 'react'; import { Router } from '@kbn/shared-ux-router'; import { waitFor } from '@testing-library/react'; -import '../../../common/mock/match_media'; import type { Filter } from '@kbn/es-query'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; import { TestProviders, createMockStore } from '../../../common/mock'; diff --git a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.test.tsx b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.test.tsx index 8b83759e47fb7..7a97cc3515d83 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock'; import { UsersTable } from '.'; diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx index 2ec81611f3c96..2a8f80ed860a4 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx @@ -9,7 +9,6 @@ import { mount } from 'enzyme'; import React from 'react'; import { Router } from '@kbn/shared-ux-router'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { Users } from './users'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 4fc2757b9f10d..f625e88e8a30c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import * as reactTestingLibrary from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { EndpointList } from '.'; -import '../../../../common/mock/match_media'; import { createUseUiSetting$Mock } from '../../../../common/lib/kibana/kibana_react.mock'; import { diff --git a/x-pack/plugins/security_solution/public/management/pages/integration_tests/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/integration_tests/index.test.tsx index d0cbd71e187c5..26936c00379c8 100644 --- a/x-pack/plugins/security_solution/public/management/pages/integration_tests/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/integration_tests/index.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { ManagementContainer } from '..'; -import '../../../common/mock/match_media'; import type { AppContextTestRender } from '../../../common/mock/endpoint'; import { createAppRootMockRenderer } from '../../../common/mock/endpoint'; import { useUserPrivileges } from '../../../common/components/user_privileges'; diff --git a/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx index 762d805ecb61b..bd4a8a3168457 100644 --- a/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx @@ -11,7 +11,6 @@ import React from 'react'; import type { OverviewHostProps } from '../overview_host'; import type { OverviewNetworkProps } from '../overview_network'; import { mockIndexPattern, TestProviders } from '../../../common/mock'; -import '../../../common/mock/match_media'; import { EventCounts } from '.'; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx index db7a23432b749..ee1148f4bd93c 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx @@ -8,7 +8,6 @@ import { mount } from 'enzyme'; import React from 'react'; -import '../../../../common/mock/match_media'; import '../../../../common/mock/react_beautiful_dnd'; import { TestProviders } from '../../../../common/mock'; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx index b1714aace87a5..11aaa1276cd8d 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import { render } from '@testing-library/react'; import React from 'react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { HostOverview } from '.'; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx index 6ae38f6b561bf..93e8d43f06750 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx @@ -8,7 +8,6 @@ import { mount } from 'enzyme'; import React from 'react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { OverviewHost } from '.'; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx index 158063f2207fe..5f2fa4c33b8dc 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx @@ -8,7 +8,6 @@ import { mount } from 'enzyme'; import React from 'react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { OverviewNetwork } from '.'; import { useNetworkOverview } from '../../containers/overview_network'; diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx index 74d78af12fde4..22c682306e12c 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import { render } from '@testing-library/react'; import React from 'react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { mockAnomalies } from '../../../common/components/ml/mock'; diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index 8423f20e52338..4f458c43bd6e8 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { merge } from 'lodash'; -import '../../common/mock/match_media'; import { TestProviders } from '../../common/mock'; import type { UseMessagesStorage } from '../../common/containers/local_storage/use_messages_storage'; import { useMessagesStorage } from '../../common/containers/local_storage/use_messages_storage'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/certificate_fingerprint/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/certificate_fingerprint/index.test.tsx index 74613f51054f4..116d58d1f669a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/certificate_fingerprint/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/certificate_fingerprint/index.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { TestProviders } from '../../../common/mock'; -import '../../../common/mock/match_media'; import { CertificateFingerprint } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/duration/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/duration/index.test.tsx index 14aa532a68917..c4989795de6fe 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/duration/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/duration/index.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { ONE_MILLISECOND_AS_NANOSECONDS } from '../formatted_duration/helpers'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx index 2c20b0bc20fac..d9edcb4cf0695 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx @@ -10,7 +10,6 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { TestProviders } from '../../../common/mock'; -import '../../../common/mock/match_media'; import { getEmptyValue } from '../../../common/components/empty_value'; import { diff --git a/x-pack/plugins/security_solution/public/timelines/components/ja3_fingerprint/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/ja3_fingerprint/index.test.tsx index 61491dd62a254..25242283c5496 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/ja3_fingerprint/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/ja3_fingerprint/index.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { TestProviders } from '../../../common/mock'; -import '../../../common/mock/match_media'; import { Ja3Fingerprint } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx index 47036a260e474..da10fcc3d0ecd 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/netflow/index.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { render, screen, within } from '@testing-library/react'; import { asArrayIfExists } from '../../../common/lib/helpers'; -import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock/test_providers'; import { TLS_CLIENT_CERTIFICATE_FINGERPRINT_SHA1_FIELD_NAME, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx index 79ea379f36142..26a6b69709640 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx @@ -11,7 +11,6 @@ import { mount } from 'enzyme'; import { fireEvent, render, waitFor } from '@testing-library/react'; import { useHistory, useParams } from 'react-router-dom'; -import '../../../common/mock/match_media'; import '../../../common/mock/formatted_relative'; import { SecurityPageName } from '../../../app/types'; import { TimelineType } from '../../../../common/api/timeline'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx index 09425094d2917..2ed4300dc7e33 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx @@ -11,7 +11,6 @@ import React from 'react'; import { ThemeProvider } from 'styled-components'; import { waitFor } from '@testing-library/react'; -import '../../../common/mock/match_media'; import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines_page'; import type { OpenTimelineResult, OpenTimelineProps } from './types'; import type { TimelinesTableProps } from './timelines_table'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx index 8e1937317113c..e3c0b2c2c5218 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx @@ -10,7 +10,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import '../../../../common/mock/match_media'; import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../../pages/timelines_page'; import type { OpenTimelineResult, OpenTimelineProps } from '../types'; import type { TimelinesTableProps } from '../timelines_table'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.test.tsx index fd78f88b9e161..459994d3cac17 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.test.tsx @@ -11,8 +11,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import '../../../../common/mock/match_media'; - import { mockTimelineResults } from '../../../../common/mock/timeline_results'; import type { OpenTimelineResult } from '../types'; import type { TimelinesTableProps } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/common_columns.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/common_columns.test.tsx index 3bc3a084217d8..b6ed788faae0c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/common_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/common_columns.test.tsx @@ -12,7 +12,6 @@ import { ThemeProvider } from 'styled-components'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import '../../../../common/mock/match_media'; import '../../../../common/mock/formatted_relative'; import { getEmptyValue } from '../../../../common/components/empty_value'; import type { OpenTimelineResult } from '../types'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/extended_columns.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/extended_columns.test.tsx index eecd1a9680219..cd6ea2eb7fb98 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/extended_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/extended_columns.test.tsx @@ -10,7 +10,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import '../../../../common/mock/match_media'; import { getEmptyValue } from '../../../../common/components/empty_value'; import { mockTimelineResults } from '../../../../common/mock/timeline_results'; import type { OpenTimelineResult } from '../types'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/icon_header_columns.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/icon_header_columns.test.tsx index 7d1dec7423800..3a286e6396ab3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/icon_header_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/icon_header_columns.test.tsx @@ -10,7 +10,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import '../../../../common/mock/match_media'; import { mockTimelineResults } from '../../../../common/mock/timeline_results'; import type { TimelinesTableProps } from '.'; import { TimelinesTable } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/index.test.tsx index c83ee49dfa38e..db8cffd770d86 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/index.test.tsx @@ -10,7 +10,6 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import '../../../../common/mock/match_media'; import { mockTimelineResults } from '../../../../common/mock/timeline_results'; import type { OpenTimelineResult } from '../types'; import type { TimelinesTableProps } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx index 2286a9af31e09..b12fdb34e7f39 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { render } from '@testing-library/react'; import { FlyoutFooter } from './footer'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock'; import { TimelineId } from '../../../../../../common/types/timeline'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx index 96b4b45f9bd16..0f186fdcf39d9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { render } from '@testing-library/react'; import { EventDetailsPanel } from '.'; -import '../../../../common/mock/match_media'; import { TestProviders } from '../../../../common/mock'; import { TimelineId, TimelineTabs } from '../../../../../common/types/timeline'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/expandable_host.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/expandable_host.test.tsx index e1e20845211af..447859854c648 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/expandable_host.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/expandable_host.test.tsx @@ -9,7 +9,6 @@ import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; import React from 'react'; -import '../../../../common/mock/match_media'; import { mockGlobalState, TestProviders } from '../../../../common/mock'; import { ExpandableHostDetails } from './expandable_host'; import { mockAnomalies } from '../../../../common/components/ml/mock'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.test.tsx index a79e5283968a3..23944e5e0170d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.test.tsx @@ -8,7 +8,6 @@ import { mount } from 'enzyme'; import React from 'react'; -import '../../../common/mock/match_media'; import { mockGlobalState, TestProviders, createMockStore } from '../../../common/mock'; import type { State } from '../../../common/store'; import { DetailsPanel } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/user_details/expandable_user.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/user_details/expandable_user.test.tsx index 8d66538a242a8..56742ba024520 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/user_details/expandable_user.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/user_details/expandable_user.test.tsx @@ -9,7 +9,6 @@ import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; import React from 'react'; -import '../../../../common/mock/match_media'; import { mockGlobalState, TestProviders } from '../../../../common/mock'; import { ExpandableUserDetails } from './expandable_user'; import { mockAnomalies } from '../../../../common/components/ml/mock'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/helpers.test.ts index 8a1aaf6295b9a..519c8d21ab70e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/helpers.test.ts @@ -6,7 +6,6 @@ */ import { mockBrowserFields } from '../../../../../common/containers/source/mock'; -import '../../../../../common/mock/match_media'; import type { BrowserFields } from '../../../../../../common/search_strategy'; import type { ColumnHeaderOptions } from '../../../../../../common/types'; import { DEFAULT_COLUMN_MIN_WIDTH, DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../constants'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx index 4042619404d27..afab121c1794c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { defaultHeaders } from './default_headers'; import { mockBrowserFields } from '../../../../../common/containers/source/mock'; import type { Sort } from '../sort'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx index 8e7a2638f4b8e..67f3c35a3ec13 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx @@ -10,7 +10,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; -import '../../../../../common/mock/match_media'; import { mockTimelineData } from '../../../../../common/mock'; import { defaultHeaders } from '../column_headers/default_headers'; import { getDefaultControlColumn } from '../control_columns'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index bb45021107311..57ba0234f0c78 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -11,7 +11,6 @@ import { waitFor } from '@testing-library/react'; import { useKibana, useCurrentUser } from '../../../../common/lib/kibana'; import { DefaultCellRenderer } from '../cell_rendering/default_cell_renderer'; -import '../../../../common/mock/match_media'; import { mockBrowserFields } from '../../../../common/containers/source/mock'; import { Direction } from '../../../../../common/search_strategy'; import { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/args.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/args.test.tsx index 687880a2e60f4..1ebd2d86c929b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/args.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/args.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { TestProviders } from '../../../../../common/mock'; import { ArgsComponent } from './args'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_details.test.tsx index 058d8105a4744..5d67b634848d5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_details.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { AuditdGenericDetails, AuditdGenericLine } from './generic_details'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_file_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_file_details.test.tsx index a28603d827538..2db90408237c7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_file_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/generic_file_details.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { AuditdGenericFileDetails, AuditdGenericFileLine } from './generic_file_details'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/primary_secondary_user_info.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/primary_secondary_user_info.test.tsx index 6aa2536e27a5a..3fa364f8a0d08 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/primary_secondary_user_info.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/primary_secondary_user_info.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { PrimarySecondaryUserInfo, nilOrUnSet } from './primary_secondary_user_info'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/session_user_host_working_dir.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/session_user_host_working_dir.test.tsx index 5392cd1640122..cfaa00633b174 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/session_user_host_working_dir.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/auditd/session_user_host_working_dir.test.tsx @@ -9,7 +9,6 @@ import { EuiFlexItem } from '@elastic/eui'; import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { SessionUserHostWorkingDir } from './session_user_host_working_dir'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/bytes/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/bytes/index.test.tsx index ef4365601e340..733afdf0b8e88 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/bytes/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/bytes/index.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { PreferenceFormattedBytes } from '../../../../../../common/components/formatted_bytes'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details.test.tsx index 78a19ba4c1990..8bb1bec15cffc 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { mockEndgameDnsRequest } from '../../../../../../common/mock/mock_endgame_ecs_data'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details_line.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details_line.test.tsx index 39fe69c498d8b..131752f65469b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details_line.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/dns/dns_request_event_details_line.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { DnsRequestEventDetailsLine } from './dns_request_event_details_line'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/empty_column_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/empty_column_renderer.test.tsx index 0e0e82fcf2f23..641d675e0bf0c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/empty_column_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/empty_column_renderer.test.tsx @@ -12,7 +12,6 @@ import React from 'react'; import { DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY } from '../../../../../common/components/drag_and_drop/translations'; import type { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { getEmptyValue } from '../../../../../common/components/empty_value'; import { deleteItemIdx, findItem } from './helpers'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details.test.tsx index b9f3b26feac8b..a3c701fa7a923 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { mockEndgameAdminLogon, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details_line.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details_line.test.tsx index 8da385e6273b0..344ecbef93c14 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details_line.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/endgame/endgame_security_event_details_line.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { EndgameSecurityEventDetailsLine } from './endgame_security_event_details_line'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/exit_code_draggable.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/exit_code_draggable.test.tsx index ae6d033db12f4..ba4e596c2050d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/exit_code_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/exit_code_draggable.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { ExitCodeDraggable } from './exit_code_draggable'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx index 404de863e26ad..20c039d46b7a8 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock'; import { FileDraggable } from './file_draggable'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx index e024d1ee9ccb6..b127b876d2b14 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { FileHash } from './file_hash'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.test.tsx index 84000ec036c28..868848acd12be 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import { get } from 'lodash/fp'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../common/mock'; import { getEmptyValue } from '../../../../../common/components/empty_value'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_column_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_column_renderer.test.tsx index 2742383a43612..551ba3c4ac570 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_column_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_column_renderer.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; -import '../../../../../common/mock/match_media'; import type { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; import { mockTimelineData } from '../../../../../common/mock'; import { TestProviders } from '../../../../../common/mock/test_providers'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx index fd85bf0a81e70..f8ed8b838ec6d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx @@ -12,7 +12,6 @@ import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; import { alertRenderer } from './alert_renderer'; -import '../../../../../common/mock/match_media'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { mockTimelineData } from '../../../../../common/mock'; import { TestProviders } from '../../../../../common/mock/test_providers'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_working_dir.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_working_dir.test.tsx index 837fe8aeab201..9009ba4dafa45 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_working_dir.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_working_dir.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../common/mock'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { HostWorkingDir } from './host_working_dir'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.test.tsx index 65defb52de782..fb399bc8478d7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/netflow/netflow_row_renderer.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import '../../../../../../common/mock/match_media'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { getMockNetflowData, TestProviders } from '../../../../../../common/mock'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/parent_process_draggable.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/parent_process_draggable.test.tsx index 2dc648049e81a..fc84273f4b324 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/parent_process_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/parent_process_draggable.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock'; import { ParentProcessDraggable } from './parent_process_draggable'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.test.tsx index a655db772a7a0..24f3c3a06074d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/plain_column_renderer.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; -import '../../../../../common/mock/match_media'; import type { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../../common/mock'; import { getEmptyValue } from '../../../../../common/components/empty_value'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_draggable.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_draggable.test.tsx index 983330008d898..6be83c5251e35 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_draggable.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { ProcessDraggable, ProcessDraggableWithNonExistentProcess } from './process_draggable'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx index b41d60fe718b5..d3b61159be361 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; import { ProcessHash } from './process_hash'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx index a13cdb5e6cdc1..1919cd22f8677 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx @@ -11,7 +11,6 @@ import { mockEndpointRegistryModificationEvent, TestProviders, } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { MODIFIED_REGISTRY_KEY } from '../system/translations'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx index 5e10374829440..d30e668ba146c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { TestProviders } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { RegistryEventDetailsLine } from './registry_event_details_line'; import { MODIFIED_REGISTRY_KEY } from '../system/translations'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx index 38155bad81a83..7a7408925cc07 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; import { mockTimelineData } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock/test_providers'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { SuricataDetails } from './suricata_details'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx index 237dd216c00cd..998916ea73ed7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx @@ -13,7 +13,6 @@ import { waitFor } from '@testing-library/react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { mockTimelineData } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock/test_providers'; import { suricataRowRenderer } from './suricata_row_renderer'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.test.tsx index c5515bd4f2d90..8f69bf0eb7271 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/auth_ssh.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/auth_ssh.test.tsx index cd081f7abcd14..12ddf856b3cca 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/auth_ssh.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/auth_ssh.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { AuthSsh } from './auth_ssh'; describe('AuthSsh', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_details.test.tsx index d9235a5056f3d..697beb1c6e92e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_details.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { SystemGenericDetails, SystemGenericLine } from './generic_details'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx index ff6ebcbd9ddde..776c00ee332b3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { mockEndgameCreationEvent } from '../../../../../../common/mock/mock_endgame_ecs_data'; import { SystemGenericFileDetails, SystemGenericFileLine } from './generic_file_details'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/package.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/package.test.tsx index 16f2eb32185b2..d6418570ffea3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/package.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/package.test.tsx @@ -8,7 +8,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { Package } from './package'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_host_working_dir.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_host_working_dir.test.tsx index fa1a92cc0b723..4033f50a48e95 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_host_working_dir.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_host_working_dir.test.tsx @@ -9,7 +9,6 @@ import { shallow } from 'enzyme'; import React from 'react'; import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { UserHostWorkingDir } from './user_host_working_dir'; import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_details.test.tsx index 717c76d0baf7a..f44d0a9401793 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_details.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; -import '../../../../../../common/mock/match_media'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { ZeekDetails } from './zeek_details'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_row_renderer.test.tsx index dff3dfda3a034..44000e4144561 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_row_renderer.test.tsx @@ -12,7 +12,6 @@ import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; -import '../../../../../../common/mock/match_media'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { zeekRowRenderer } from './zeek_row_renderer'; import { TimelineId } from '../../../../../../../common/types/timeline'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.test.tsx index 8b2287ff5fa81..f5aae3384c411 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.test.tsx @@ -10,7 +10,6 @@ import { cloneDeep } from 'lodash/fp'; import React from 'react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; -import '../../../../../../common/mock/match_media'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { mockTimelineData, TestProviders } from '../../../../../../common/mock'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx index 83b4ebf55bcfb..a8f2ba2121dd8 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import useResizeObserver from 'use-resize-observer/polyfilled'; import { DragDropContextWrapper } from '../../../common/components/drag_and_drop/drag_drop_context_wrapper'; -import '../../../common/mock/match_media'; import { mockBrowserFields } from '../../../common/containers/source/mock'; import { TimelineId } from '../../../../common/types/timeline'; import { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx index 2fef17e588058..233deb0276ce5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx @@ -12,7 +12,6 @@ import useResizeObserver from 'use-resize-observer/polyfilled'; import { defaultRowRenderers } from '../../body/renderers'; import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; import { defaultHeaders, mockTimelineData } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock/test_providers'; import type { Props as EqlTabContentComponentProps } from '.'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.test.tsx index 665019123e37f..adf3d8d9aa6b2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.test.tsx @@ -11,7 +11,6 @@ import useResizeObserver from 'use-resize-observer/polyfilled'; import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; import { defaultHeaders, mockTimelineData } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock/test_providers'; import { defaultRowRenderers } from '../../body/renderers'; import type { Sort } from '../../body/sort'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx index 2f81f67b18176..d1c12f693eeed 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx @@ -11,7 +11,6 @@ import useResizeObserver from 'use-resize-observer/polyfilled'; import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; import { defaultHeaders, mockTimelineData } from '../../../../../common/mock'; -import '../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../common/mock/test_providers'; import type { Props as QueryTabContentComponentProps } from '.'; diff --git a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx index dcc8dd53c7986..4b2ca534c97a1 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx @@ -28,24 +28,6 @@ describe('SessionView component', () => { let mockedContext: AppContextTestRender; let mockedApi: AppContextTestRender['coreStart']['http']['get']; - beforeAll(() => { - // https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function - // xtermjs is using window.matchMedia, which isn't mocked in jest by default. - Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // Deprecated - removeListener: jest.fn(), // Deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), - }); - }); - beforeEach(() => { mockedContext = createAppRootMockRenderer(); mockedApi = mockedContext.coreStart.http.get; diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx index 40b35e7ee3f24..e631fac8d6d24 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx @@ -14,22 +14,6 @@ const VIM_LINE_START = 22; describe('TTYPlayer/hooks', () => { beforeAll(() => { - // https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function - // xtermjs is using window.matchMedia, which isn't mocked in jest by default. - Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // Deprecated - removeListener: jest.fn(), // Deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), - }); - jest.useFakeTimers({ legacyFakeTimers: true }); }); diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx index 327d39da48d00..77d58c6e1b436 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx @@ -17,24 +17,6 @@ import { TTYPlayerDeps, TTYPlayer } from '.'; import userEvent from '@testing-library/user-event'; describe('TTYPlayer component', () => { - beforeAll(() => { - // https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function - // xtermjs is using window.matchMedia, which isn't mocked in jest by default. - Object.defineProperty(window, 'matchMedia', { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // Deprecated - removeListener: jest.fn(), // Deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), - }); - }); - let render: () => ReturnType; let renderResult: ReturnType; let mockedContext: AppContextTestRender; From d83a7370f92a7bf3d5973bf30ac8799df941a250 Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Tue, 30 Apr 2024 14:38:30 +0200 Subject: [PATCH 035/104] [Maintenance] Move Asset Manager, Metrics Data Access to `/x-pack/plugins/observability_solution` (#181970) ## Summary Title says it all. --- .github/CODEOWNERS | 4 +- docs/developer/plugin-list.asciidoc | 4 +- package.json | 4 +- tsconfig.base.json | 12 +- x-pack/.i18nrc.json | 62 ++--- .../asset_manager/README.md | 0 .../asset_manager/common/config.ts | 0 .../asset_manager/common/constants_routes.ts | 0 .../asset_manager/common/debug_log.ts | 0 .../asset_manager/common/types_api.ts | 0 .../asset_manager/common/types_client.ts | 0 .../asset_manager/docs/api.md | 230 +++++++++--------- .../asset_manager/docs/development.md | 0 .../asset_manager/docs/rest_deprecated.md | 0 .../asset_manager/docs/schema/index.md | 0 .../asset_manager/jest.config.js | 9 +- .../asset_manager/kibana.jsonc | 0 .../asset_manager/public/index.ts | 0 .../public/lib/public_assets_client.test.ts | 0 .../public/lib/public_assets_client.ts | 0 .../asset_manager/public/plugin.ts | 0 .../asset_manager/public/types.ts | 0 .../asset_manager/server/constants.ts | 0 .../asset_manager/server/index.ts | 0 .../containers/get_containers.test.ts | 0 .../accessors/containers/get_containers.ts | 0 .../lib/accessors/hosts/get_hosts.test.ts | 0 .../server/lib/accessors/hosts/get_hosts.ts | 0 .../lib/accessors/pods/get_pods.test.ts | 0 .../server/lib/accessors/pods/get_pods.ts | 0 .../lib/accessors/services/get_services.ts | 0 .../server/lib/asset_client.test.ts | 0 .../asset_manager/server/lib/asset_client.ts | 0 .../server/lib/asset_client_types.ts | 0 .../server/lib/collectors/containers.ts | 0 .../server/lib/collectors/hosts.ts | 0 .../server/lib/collectors/index.ts | 0 .../server/lib/collectors/pods.ts | 0 .../server/lib/collectors/services.ts | 0 .../asset_manager/server/lib/errors.ts | 0 .../server/lib/manage_index_templates.ts | 0 .../server/lib/parse_ean.test.ts | 0 .../asset_manager/server/lib/parse_ean.ts | 0 .../asset_manager/server/lib/sample_assets.ts | 0 .../asset_manager/server/lib/utils.ts | 0 .../lib/validators/validate_date_range.ts | 0 .../server/lib/validators/validation_error.ts | 0 .../asset_manager/server/lib/write_assets.ts | 0 .../asset_manager/server/plugin.ts | 0 .../server/routes/assets/containers.ts | 0 .../server/routes/assets/hosts.ts | 0 .../server/routes/assets/index.ts | 0 .../server/routes/assets/pods.ts | 0 .../server/routes/assets/services.ts | 0 .../asset_manager/server/routes/index.ts | 0 .../asset_manager/server/routes/ping.ts | 0 .../server/routes/sample_assets.ts | 0 .../asset_manager/server/routes/types.ts | 0 .../asset_manager/server/routes/utils.ts | 0 .../server/templates/assets_template.ts | 0 .../asset_manager/server/test_utils.ts | 0 .../asset_manager/server/types.ts | 0 .../asset_manager/tsconfig.json | 4 +- .../metrics_data_access/README.md | 0 .../common/alerting/metrics/index.ts | 0 .../common/alerting/metrics/types.ts | 0 .../common/color_palette.ts | 0 .../metrics_data_access/common/constants.ts | 0 .../common/http_api/index.ts | 0 .../common/http_api/metric_indices.ts | 0 .../common/http_api/metrics_api.ts | 0 .../common/http_api/metrics_explorer.ts | 0 .../metrics_data_access/common/index.ts | 0 .../common/inventory_models/aws_ec2/index.ts | 0 .../inventory_models/aws_ec2/metrics/index.ts | 0 .../aws_ec2/metrics/snapshot/cpu.ts | 0 .../metrics/snapshot/disk_io_read_bytes.ts | 0 .../metrics/snapshot/disk_io_write_bytes.ts | 0 .../aws_ec2/metrics/snapshot/rx.ts | 0 .../aws_ec2/metrics/snapshot/tx.ts | 0 .../metrics/tsvb/aws_ec2_cpu_utilization.ts | 0 .../metrics/tsvb/aws_ec2_diskio_bytes.ts | 0 .../metrics/tsvb/aws_ec2_network_traffic.ts | 0 .../common/inventory_models/aws_rds/index.ts | 0 .../inventory_models/aws_rds/metrics/index.ts | 0 .../aws_rds/metrics/snapshot/cpu.ts | 0 .../snapshot/rds_active_transactions.ts | 0 .../metrics/snapshot/rds_connections.ts | 0 .../aws_rds/metrics/snapshot/rds_latency.ts | 0 .../metrics/snapshot/rds_queries_executed.ts | 0 .../tsvb/aws_rds_active_transactions.ts | 0 .../metrics/tsvb/aws_rds_connections.ts | 0 .../aws_rds/metrics/tsvb/aws_rds_cpu_total.ts | 0 .../aws_rds/metrics/tsvb/aws_rds_latency.ts | 0 .../metrics/tsvb/aws_rds_queries_executed.ts | 0 .../common/inventory_models/aws_s3/index.ts | 0 .../inventory_models/aws_s3/metrics/index.ts | 0 .../aws_s3/metrics/snapshot/s3_bucket_size.ts | 0 .../metrics/snapshot/s3_download_bytes.ts | 0 .../metrics/snapshot/s3_number_of_objects.ts | 0 .../metrics/snapshot/s3_total_requests.ts | 0 .../metrics/snapshot/s3_upload_bytes.ts | 0 .../aws_s3/metrics/tsvb/aws_s3_bucket_size.ts | 0 .../metrics/tsvb/aws_s3_download_bytes.ts | 0 .../metrics/tsvb/aws_s3_number_of_objects.ts | 0 .../metrics/tsvb/aws_s3_total_requests.ts | 0 .../metrics/tsvb/aws_s3_upload_bytes.ts | 0 .../common/inventory_models/aws_sqs/index.ts | 0 .../inventory_models/aws_sqs/metrics/index.ts | 0 .../metrics/snapshot/sqs_messages_delayed.ts | 0 .../metrics/snapshot/sqs_messages_empty.ts | 0 .../metrics/snapshot/sqs_messages_sent.ts | 0 .../metrics/snapshot/sqs_messages_visible.ts | 0 .../metrics/snapshot/sqs_oldest_message.ts | 0 .../metrics/tsvb/aws_sqs_messages_delayed.ts | 0 .../metrics/tsvb/aws_sqs_messages_empty.ts | 0 .../metrics/tsvb/aws_sqs_messages_sent.ts | 0 .../metrics/tsvb/aws_sqs_messages_visible.ts | 0 .../metrics/tsvb/aws_sqs_oldest_message.ts | 0 .../inventory_models/container/index.ts | 0 .../container/metrics/index.ts | 0 .../container/metrics/snapshot/cpu.ts | 0 .../container/metrics/snapshot/memory.ts | 0 .../container/metrics/snapshot/rx.ts | 0 .../container/metrics/snapshot/tx.ts | 0 .../metrics/tsvb/container_cpu_kernel.ts | 0 .../metrics/tsvb/container_cpu_usage.ts | 0 .../metrics/tsvb/container_disk_io_bytes.ts | 0 .../metrics/tsvb/container_diskio_ops.ts | 0 .../metrics/tsvb/container_k8s_cpu_usage.ts | 0 .../tsvb/container_k8s_memory_usage.ts | 0 .../metrics/tsvb/container_k8s_overview.ts | 0 .../metrics/tsvb/container_memory.ts | 0 .../metrics/tsvb/container_network_traffic.ts | 0 .../metrics/tsvb/container_overview.ts | 0 .../inventory_models/create_tsvb_model.ts | 0 .../common/inventory_models/host/index.ts | 0 .../host/metrics/charts/cpu.ts | 0 .../host/metrics/charts/disk.ts | 0 .../host/metrics/charts/index.ts | 0 .../host/metrics/charts/logs.ts | 0 .../host/metrics/charts/memory.ts | 0 .../host/metrics/charts/network.ts | 0 .../host/metrics/formulas/cpu.ts | 0 .../host/metrics/formulas/disk.ts | 0 .../host/metrics/formulas/host_count.ts | 0 .../host/metrics/formulas/index.ts | 0 .../host/metrics/formulas/log_rate.ts | 0 .../host/metrics/formulas/memory.ts | 0 .../host/metrics/formulas/network.ts | 0 .../inventory_models/host/metrics/index.ts | 0 .../host/metrics/snapshot/cpu.ts | 0 .../host/metrics/snapshot/disk_latency.ts | 0 .../host/metrics/snapshot/disk_space_usage.ts | 0 .../host/metrics/snapshot/index.ts | 0 .../host/metrics/snapshot/load.ts | 0 .../host/metrics/snapshot/log_rate.ts | 0 .../host/metrics/snapshot/memory.ts | 0 .../host/metrics/snapshot/memory_free.ts | 0 .../host/metrics/snapshot/memory_total.ts | 0 .../metrics/snapshot/normalized_load_1m.ts | 0 .../host/metrics/snapshot/rx.ts | 0 .../host/metrics/snapshot/tx.ts | 0 .../host/metrics/tsvb/host_cpu_usage.ts | 0 .../host/metrics/tsvb/host_docker_info.ts | 0 .../host/metrics/tsvb/host_docker_overview.ts | 0 .../metrics/tsvb/host_docker_top_5_by_cpu.ts | 0 .../tsvb/host_docker_top_5_by_memory.ts | 0 .../host/metrics/tsvb/host_filesystem.ts | 0 .../host/metrics/tsvb/host_k8s_cpu_cap.ts | 0 .../host/metrics/tsvb/host_k8s_disk_cap.ts | 0 .../host/metrics/tsvb/host_k8s_memory_cap.ts | 0 .../host/metrics/tsvb/host_k8s_overview.ts | 0 .../host/metrics/tsvb/host_k8s_pod_cap.ts | 0 .../host/metrics/tsvb/host_load.ts | 0 .../host/metrics/tsvb/host_memory_usage.ts | 0 .../host/metrics/tsvb/host_network_traffic.ts | 0 .../host/metrics/tsvb/host_system_overview.ts | 0 .../host/metrics/tsvb/index.ts | 0 .../common/inventory_models/index.ts | 0 .../kubernetes/node/metrics/charts/index.ts | 0 .../kubernetes/node/metrics/charts/node.ts | 0 .../kubernetes/node/metrics/formulas/cpu.ts | 0 .../kubernetes/node/metrics/formulas/disk.ts | 0 .../kubernetes/node/metrics/formulas/index.ts | 0 .../node/metrics/formulas/memory.ts | 0 .../node/metrics/formulas/pod_capacity.ts | 0 .../kubernetes/node/metrics/index.ts | 0 .../inventory_models/kubernetes/pod/index.ts | 0 .../kubernetes/pod/metrics/index.ts | 0 .../kubernetes/pod/metrics/snapshot/cpu.ts | 0 .../kubernetes/pod/metrics/snapshot/memory.ts | 0 .../kubernetes/pod/metrics/snapshot/rx.ts | 0 .../kubernetes/pod/metrics/snapshot/tx.ts | 0 .../pod/metrics/tsvb/pod_cpu_usage.ts | 0 .../pod/metrics/tsvb/pod_log_usage.ts | 0 .../pod/metrics/tsvb/pod_memory_usage.ts | 0 .../pod/metrics/tsvb/pod_network_traffic.ts | 0 .../pod/metrics/tsvb/pod_overview.ts | 0 .../common/inventory_models/metrics.ts | 0 .../shared/charts/constants.ts | 0 .../inventory_models/shared/metrics/index.ts | 0 .../shared/metrics/required_metrics.ts | 0 .../shared/metrics/snapshot/count.ts | 0 .../metrics/snapshot/network_traffic.ts | 0 .../network_traffic_with_interfaces.ts | 0 .../shared/metrics/snapshot/rate.ts | 0 .../metrics/tsvb/aws_cpu_utilization.ts | 0 .../shared/metrics/tsvb/aws_diskio_bytes.ts | 0 .../shared/metrics/tsvb/aws_diskio_ops.ts | 0 .../shared/metrics/tsvb/aws_network_bytes.ts | 0 .../metrics/tsvb/aws_network_packets.ts | 0 .../shared/metrics/tsvb/aws_overview.ts | 0 .../metrics/tsvb/nginx_active_connections.ts | 0 .../shared/metrics/tsvb/nginx_hits.ts | 0 .../shared/metrics/tsvb/nginx_request_rate.ts | 0 .../tsvb/nginx_requests_per_connection.ts | 0 .../common/inventory_models/types.ts | 0 .../common/metrics_explorer_views/types.ts | 0 .../common/runtime_types.ts | 0 .../common/utility_types.ts | 0 .../metrics_data_access/jest.config.js | 7 +- .../metrics_data_access/kibana.jsonc | 0 .../public/apps/common_providers.tsx | 0 .../public/components/empty_states/index.tsx | 0 .../components/empty_states/no_data.tsx | 0 .../components/empty_states/no_indices.tsx | 0 .../empty_states/no_metric_indices.tsx | 0 .../empty_states/no_remote_cluster.tsx | 0 .../README.md | 0 .../container_metrics_table.stories.tsx | 0 .../container_metrics_table.test.tsx | 0 .../container/container_metrics_table.tsx | 0 .../create_lazy_container_metrics_table.tsx | 0 .../container/index.ts | 0 .../integrated_container_metrics_table.tsx | 0 .../use_container_metrics_table.test.ts | 0 .../container/use_container_metrics_table.ts | 0 .../host/create_lazy_host_metrics_table.tsx | 0 .../host/host_metrics_table.stories.tsx | 0 .../host/host_metrics_table.test.tsx | 0 .../host/host_metrics_table.tsx | 0 .../host/index.ts | 0 .../host/integrated_host_metrics_table.tsx | 0 .../host/use_host_metrics_table.test.ts | 0 .../host/use_host_metrics_table.ts | 0 .../index.ts | 0 .../pod/create_lazy_pod_metrics_table.tsx | 0 .../pod/index.ts | 0 .../pod/integrated_pod_metrics_table.tsx | 0 .../pod/pod_metrics_table.stories.tsx | 0 .../pod/pod_metrics_table.test.tsx | 0 .../pod/pod_metrics_table.tsx | 0 .../pod/use_pod_metrics_table.test.ts | 0 .../pod/use_pod_metrics_table.ts | 0 .../components/assets/no_results_dark.svg | 0 .../components/assets/no_results_light.svg | 0 .../shared/components/error_content.tsx | 0 .../shared/components/index.ts | 0 .../components/metrics_node_details_link.tsx | 0 .../shared/components/no_data_content.tsx | 0 .../shared/components/number_cell.tsx | 0 .../shared/components/stepwise_pagination.tsx | 0 .../shared/hooks/helpers.ts | 0 .../shared/hooks/index.ts | 0 .../hooks/metrics_to_api_options.test.ts | 0 .../shared/hooks/metrics_to_api_options.ts | 0 .../hooks/use_infrastructure_node_metrics.ts | 0 .../shared/index.ts | 0 .../shared/types.ts | 0 .../test_helpers.ts | 0 .../public/hooks/use_kibana.tsx | 0 .../metrics_data_access/public/index.ts | 0 .../public/lib/metrics_client.ts | 0 .../public/pages/link_to/index.ts | 0 .../link_to/use_node_details_redirect.ts | 0 .../metrics_data_access/public/plugin.ts | 0 .../public/test_utils/index.ts | 0 .../test_utils/use_global_storybook_theme.tsx | 0 .../metrics_data_access/public/types.ts | 0 .../public/utils/use_tracked_promise.ts | 0 .../server/client/client.test.ts | 0 .../server/client/client.ts | 0 .../server/client/index.ts | 0 .../metrics_data_access/server/client_mock.ts | 0 .../metrics_data_access/server/index.ts | 0 .../lib/adapters/framework/adapter_types.ts | 0 .../server/lib/adapters/framework/index.ts | 0 .../framework/kibana_framework_adapter.ts | 0 .../lib/adapters/metrics/adapter_types.ts | 0 .../server/lib/adapters/metrics/index.ts | 0 .../lib/create_custom_metrics_aggregations.ts | 0 .../server/lib/create_search_client.ts | 0 .../server/lib/metrics/constants.ts | 0 .../server/lib/metrics/index.ts | 0 ...ert_buckets_to_metrics_series.test.ts.snap | 0 .../create_aggregations.test.ts.snap | 0 .../create_metrics_aggregations.test.ts.snap | 0 .../calculate_auto.test.ts | 0 .../calculate_bucket_size/calculate_auto.ts | 0 .../calculate_bucket_size.test.ts | 0 .../lib/calculate_bucket_size/index.ts | 0 .../interval_regex.test.ts | 0 .../calculate_bucket_size/interval_regex.ts | 0 .../unit_to_seconds.test.ts | 0 .../calculate_bucket_size/unit_to_seconds.ts | 0 .../calculate_date_histogram_offset.test.ts | 0 .../lib/calculate_date_histogram_offset.ts | 0 .../lib/metrics/lib/calculate_interval.ts | 0 .../convert_buckets_to_metrics_series.test.ts | 0 .../lib/convert_buckets_to_metrics_series.ts | 0 .../metrics/lib/create_aggregations.test.ts | 0 .../lib/metrics/lib/create_aggregations.ts | 0 .../lib/create_metrics_aggregations.test.ts | 0 .../lib/create_metrics_aggregations.ts | 0 .../server/lib/metrics/types.ts | 0 .../metrics_data_access/server/plugin.ts | 0 .../server/routes/metric_indices/index.ts | 0 .../server/routes/metrics_explorer/index.ts | 0 ...nvert_metric_to_metrics_api_metric.test.ts | 0 .../convert_metric_to_metrics_api_metric.ts | 0 ...ert_request_to_metrics_api_options.test.ts | 0 .../convert_request_to_metrics_api_options.ts | 0 .../lib/find_interval_for_metrics.ts | 0 .../lib/get_dataset_for_field.ts | 0 .../lib/query_total_grouping.test.ts | 0 .../lib/query_total_groupings.ts | 0 .../metrics_explorer/lib/transform_series.ts | 0 .../server/routes/types.ts | 0 .../metrics_data_source/index.ts | 0 .../metrics_data_access/server/types.ts | 0 .../server/utils/calculate_metric_interval.ts | 0 .../metrics_data_access/tsconfig.json | 4 +- yarn.lock | 4 +- 334 files changed, 152 insertions(+), 192 deletions(-) rename x-pack/plugins/{ => observability_solution}/asset_manager/README.md (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/common/config.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/common/constants_routes.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/common/debug_log.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/common/types_api.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/common/types_client.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/docs/api.md (57%) rename x-pack/plugins/{ => observability_solution}/asset_manager/docs/development.md (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/docs/rest_deprecated.md (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/docs/schema/index.md (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/jest.config.js (52%) rename x-pack/plugins/{ => observability_solution}/asset_manager/kibana.jsonc (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/public/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/public/lib/public_assets_client.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/public/lib/public_assets_client.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/public/plugin.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/public/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/constants.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/containers/get_containers.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/containers/get_containers.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/hosts/get_hosts.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/hosts/get_hosts.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/pods/get_pods.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/pods/get_pods.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/accessors/services/get_services.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/asset_client.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/asset_client.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/asset_client_types.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/collectors/containers.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/collectors/hosts.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/collectors/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/collectors/pods.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/collectors/services.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/errors.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/manage_index_templates.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/parse_ean.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/parse_ean.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/sample_assets.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/utils.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/validators/validate_date_range.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/validators/validation_error.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/lib/write_assets.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/plugin.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/assets/containers.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/assets/hosts.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/assets/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/assets/pods.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/assets/services.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/ping.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/sample_assets.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/routes/utils.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/templates/assets_template.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/test_utils.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/server/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/asset_manager/tsconfig.json (90%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/README.md (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/alerting/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/alerting/metrics/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/color_palette.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/constants.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/http_api/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/http_api/metric_indices.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/http_api/metrics_api.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/http_api/metrics_explorer.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_read_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_write_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/rx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/tx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_cpu_utilization.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_diskio_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_network_traffic.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_active_transactions.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_connections.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_latency.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_queries_executed.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_active_transactions.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_connections.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_cpu_total.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_latency.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_queries_executed.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_bucket_size.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_download_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_number_of_objects.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_total_requests.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_upload_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_bucket_size.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_download_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_number_of_objects.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_total_requests.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_upload_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_delayed.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_empty.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_sent.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_visible.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_oldest_message.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_delayed.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_empty.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_sent.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_visible.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_oldest_message.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/snapshot/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/snapshot/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/snapshot/rx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/snapshot/tx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_kernel.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_disk_io_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_diskio_ops.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_cpu_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_memory_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_network_traffic.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/create_tsvb_model.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/disk.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/logs.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/disk.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/host_count.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/log_rate.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/formulas/network.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_latency.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_space_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/load.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/log_rate.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_free.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_total.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/normalized_load_1m.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/rx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/snapshot/tx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_info.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_filesystem.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_load.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_system_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/host/metrics/tsvb/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/node.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/disk.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/pod_capacity.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/node/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/cpu.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/memory.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/rx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/tx.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_cpu_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_log_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_memory_usage.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_network_traffic.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/metrics.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/charts/constants.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/required_metrics.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/snapshot/count.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic_with_interfaces.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/snapshot/rate.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_overview.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_active_connections.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_hits.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_request_rate.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_requests_per_connection.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/inventory_models/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/metrics_explorer_views/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/runtime_types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/common/utility_types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/jest.config.js (64%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/kibana.jsonc (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/apps/common_providers.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/empty_states/index.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/empty_states/no_data.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/empty_states/no_indices.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/empty_states/no_metric_indices.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/empty_states/no_remote_cluster.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/README.md (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.stories.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.test.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/create_lazy_container_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/integrated_container_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/create_lazy_host_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.stories.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.test.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/integrated_host_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/create_lazy_pod_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/integrated_pod_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.stories.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.test.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_dark.svg (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_light.svg (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/error_content.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/metrics_node_details_link.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/no_data_content.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/number_cell.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/stepwise_pagination.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/helpers.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/use_infrastructure_node_metrics.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/components/infrastructure_node_metrics_tables/test_helpers.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/hooks/use_kibana.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/lib/metrics_client.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/pages/link_to/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/pages/link_to/use_node_details_redirect.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/plugin.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/test_utils/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/public/utils/use_tracked_promise.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/client/client.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/client/client.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/client/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/client_mock.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/adapters/framework/adapter_types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/adapters/framework/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/adapters/framework/kibana_framework_adapter.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/adapters/metrics/adapter_types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/adapters/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/create_custom_metrics_aggregations.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/create_search_client.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/constants.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/__snapshots__/convert_buckets_to_metrics_series.test.ts.snap (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_metrics_aggregations.test.ts.snap (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_bucket_size.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/calculate_interval.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/create_aggregations.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/create_aggregations.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/lib/metrics/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/plugin.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metric_indices/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/get_dataset_for_field.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/query_total_grouping.test.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/query_total_groupings.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/metrics_explorer/lib/transform_series.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/routes/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/saved_objects/metrics_data_source/index.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/types.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/server/utils/calculate_metric_interval.ts (100%) rename x-pack/plugins/{ => observability_solution}/metrics_data_access/tsconfig.json (87%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e85da3abf6ec2..9d536165aa69a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -51,7 +51,7 @@ packages/kbn-apm-synthtrace-client @elastic/obs-ux-infra_services-team @elastic/ packages/kbn-apm-utils @elastic/obs-ux-infra_services-team test/plugin_functional/plugins/app_link_test @elastic/kibana-core x-pack/test/usage_collection/plugins/application_usage_test @elastic/kibana-core -x-pack/plugins/asset_manager @elastic/obs-knowledge-team +x-pack/plugins/observability_solution/asset_manager @elastic/obs-knowledge-team x-pack/test/security_api_integration/plugins/audit_log @elastic/kibana-security packages/kbn-axe-config @elastic/kibana-qa packages/kbn-babel-preset @elastic/kibana-operations @@ -555,7 +555,7 @@ x-pack/examples/third_party_maps_source_example @elastic/kibana-gis src/plugins/maps_ems @elastic/kibana-gis x-pack/plugins/maps @elastic/kibana-gis x-pack/packages/maps/vector_tile_utils @elastic/kibana-gis -x-pack/plugins/metrics_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team +x-pack/plugins/observability_solution/metrics_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team x-pack/packages/ml/agg_utils @elastic/ml-ui x-pack/packages/ml/anomaly_utils @elastic/ml-ui x-pack/packages/ml/cancellable_search @elastic/ml-ui diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 3bbc594a21c5a..75d681625b1ba 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -462,7 +462,7 @@ The plugin exposes the static DefaultEditorController class to consume. |WARNING: Missing README. -|{kib-repo}blob/{branch}/x-pack/plugins/asset_manager/README.md[assetManager] +|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/asset_manager/README.md[assetManager] |This plugin provides access to observed asset data, such as information about hosts, pods, containers, services, and more. @@ -659,7 +659,7 @@ using the CURL scripts in the scripts folder. |Visualize geo data from Elasticsearch or 3rd party geo-services. -|{kib-repo}blob/{branch}/x-pack/plugins/metrics_data_access/README.md[metricsDataAccess] +|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/metrics_data_access/README.md[metricsDataAccess] |Exposes utilities to access metrics data. diff --git a/package.json b/package.json index dc0e1b763c80d..ec2b1806feea2 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "@kbn/apm-utils": "link:packages/kbn-apm-utils", "@kbn/app-link-test-plugin": "link:test/plugin_functional/plugins/app_link_test", "@kbn/application-usage-test-plugin": "link:x-pack/test/usage_collection/plugins/application_usage_test", - "@kbn/assetManager-plugin": "link:x-pack/plugins/asset_manager", + "@kbn/assetManager-plugin": "link:x-pack/plugins/observability_solution/asset_manager", "@kbn/audit-log-plugin": "link:x-pack/test/security_api_integration/plugins/audit_log", "@kbn/banners-plugin": "link:x-pack/plugins/banners", "@kbn/bfetch-error": "link:packages/kbn-bfetch-error", @@ -577,7 +577,7 @@ "@kbn/maps-ems-plugin": "link:src/plugins/maps_ems", "@kbn/maps-plugin": "link:x-pack/plugins/maps", "@kbn/maps-vector-tile-utils": "link:x-pack/packages/maps/vector_tile_utils", - "@kbn/metrics-data-access-plugin": "link:x-pack/plugins/metrics_data_access", + "@kbn/metrics-data-access-plugin": "link:x-pack/plugins/observability_solution/metrics_data_access", "@kbn/ml-agg-utils": "link:x-pack/packages/ml/agg_utils", "@kbn/ml-anomaly-utils": "link:x-pack/packages/ml/anomaly_utils", "@kbn/ml-cancellable-search": "link:x-pack/packages/ml/cancellable_search", diff --git a/tsconfig.base.json b/tsconfig.base.json index 6f59b5dcfceea..a887de77dafbc 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -96,8 +96,8 @@ "@kbn/app-link-test-plugin/*": ["test/plugin_functional/plugins/app_link_test/*"], "@kbn/application-usage-test-plugin": ["x-pack/test/usage_collection/plugins/application_usage_test"], "@kbn/application-usage-test-plugin/*": ["x-pack/test/usage_collection/plugins/application_usage_test/*"], - "@kbn/assetManager-plugin": ["x-pack/plugins/asset_manager"], - "@kbn/assetManager-plugin/*": ["x-pack/plugins/asset_manager/*"], + "@kbn/assetManager-plugin": ["x-pack/plugins/observability_solution/asset_manager"], + "@kbn/assetManager-plugin/*": ["x-pack/plugins/observability_solution/asset_manager/*"], "@kbn/audit-log-plugin": ["x-pack/test/security_api_integration/plugins/audit_log"], "@kbn/audit-log-plugin/*": ["x-pack/test/security_api_integration/plugins/audit_log/*"], "@kbn/axe-config": ["packages/kbn-axe-config"], @@ -1104,8 +1104,8 @@ "@kbn/maps-plugin/*": ["x-pack/plugins/maps/*"], "@kbn/maps-vector-tile-utils": ["x-pack/packages/maps/vector_tile_utils"], "@kbn/maps-vector-tile-utils/*": ["x-pack/packages/maps/vector_tile_utils/*"], - "@kbn/metrics-data-access-plugin": ["x-pack/plugins/metrics_data_access"], - "@kbn/metrics-data-access-plugin/*": ["x-pack/plugins/metrics_data_access/*"], + "@kbn/metrics-data-access-plugin": ["x-pack/plugins/observability_solution/metrics_data_access"], + "@kbn/metrics-data-access-plugin/*": ["x-pack/plugins/observability_solution/metrics_data_access/*"], "@kbn/ml-agg-utils": ["x-pack/packages/ml/agg_utils"], "@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"], "@kbn/ml-anomaly-utils": ["x-pack/packages/ml/anomaly_utils"], @@ -1832,9 +1832,7 @@ "@kbn/zod-helpers/*": ["packages/kbn-zod-helpers/*"], // END AUTOMATED PACKAGE LISTING // Allows for importing from `kibana` package for the exported types. - "@emotion/core": [ - "typings/@emotion" - ] + "@emotion/core": ["typings/@emotion"] }, // Support .tsx files and transform JSX into calls to React.createElement "jsx": "react", diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index b51b54043398c..36885e2574f63 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -38,15 +38,9 @@ "xpack.dataVisualizer": "plugins/data_visualizer", "xpack.exploratoryView": "plugins/observability_solution/exploratory_view", "xpack.fileUpload": "plugins/file_upload", - "xpack.globalSearch": [ - "plugins/global_search" - ], - "xpack.globalSearchBar": [ - "plugins/global_search_bar" - ], - "xpack.graph": [ - "plugins/graph" - ], + "xpack.globalSearch": ["plugins/global_search"], + "xpack.globalSearchBar": ["plugins/global_search_bar"], + "xpack.graph": ["plugins/graph"], "xpack.grokDebugger": "plugins/grokdebugger", "xpack.idxMgmt": "plugins/index_management", "xpack.idxMgmtPackage": "packages/index-management", @@ -62,14 +56,10 @@ "xpack.licenseMgmt": "plugins/license_management", "xpack.licensing": "plugins/licensing", "xpack.lists": "plugins/lists", - "xpack.logstash": [ - "plugins/logstash" - ], + "xpack.logstash": ["plugins/logstash"], "xpack.main": "legacy/plugins/xpack_main", - "xpack.maps": [ - "plugins/maps" - ], - "xpack.metricsData": "plugins/metrics_data_access", + "xpack.maps": ["plugins/maps"], + "xpack.metricsData": "plugins/observability_solution/metrics_data_access", "xpack.ml": [ "packages/ml/anomaly_utils", "packages/ml/creation_wizard_utils", @@ -82,9 +72,7 @@ "packages/ml/ui_actions", "plugins/ml" ], - "xpack.monitoring": [ - "plugins/monitoring" - ], + "xpack.monitoring": ["plugins/monitoring"], "xpack.observability": "plugins/observability_solution/observability", "xpack.observabilityAiAssistant": [ "plugins/observability_solution/observability_ai_assistant", @@ -94,20 +82,12 @@ "xpack.observabilityLogsExplorer": "plugins/observability_solution/observability_logs_explorer", "xpack.observability_onboarding": "plugins/observability_solution/observability_onboarding", "xpack.observabilityShared": "plugins/observability_solution/observability_shared", - "xpack.osquery": [ - "plugins/osquery" - ], + "xpack.osquery": ["plugins/osquery"], "xpack.painlessLab": "plugins/painless_lab", - "xpack.profiling": [ - "plugins/observability_solution/profiling" - ], + "xpack.profiling": ["plugins/observability_solution/profiling"], "xpack.remoteClusters": "plugins/remote_clusters", - "xpack.reporting": [ - "plugins/reporting" - ], - "xpack.rollupJobs": [ - "plugins/rollup" - ], + "xpack.reporting": ["plugins/reporting"], + "xpack.rollupJobs": ["plugins/rollup"], "xpack.runtimeFields": "plugins/runtime_fields", "xpack.screenshotting": "plugins/screenshotting", "xpack.searchNotebooks": "plugins/search_notebooks", @@ -125,30 +105,20 @@ "xpack.slo": "plugins/observability_solution/slo", "xpack.snapshotRestore": "plugins/snapshot_restore", "xpack.spaces": "plugins/spaces", - "xpack.savedObjectsTagging": [ - "plugins/saved_objects_tagging" - ], + "xpack.savedObjectsTagging": ["plugins/saved_objects_tagging"], "xpack.taskManager": "legacy/plugins/task_manager", "xpack.threatIntelligence": "plugins/threat_intelligence", "xpack.timelines": "plugins/timelines", "xpack.transform": "plugins/transform", "xpack.triggersActionsUI": "plugins/triggers_actions_ui", "xpack.upgradeAssistant": "plugins/upgrade_assistant", - "xpack.uptime": [ - "plugins/observability_solution/uptime" - ], - "xpack.synthetics": [ - "plugins/observability_solution/synthetics" - ], - "xpack.ux": [ - "plugins/observability_solution/ux" - ], + "xpack.uptime": ["plugins/observability_solution/uptime"], + "xpack.synthetics": ["plugins/observability_solution/synthetics"], + "xpack.ux": ["plugins/observability_solution/ux"], "xpack.urlDrilldown": "plugins/drilldowns/url_drilldown", "xpack.watcher": "plugins/watcher" }, - "exclude": [ - "examples" - ], + "exclude": ["examples"], "translations": [ "@kbn/translations-plugin/translations/zh-CN.json", "@kbn/translations-plugin/translations/ja-JP.json", diff --git a/x-pack/plugins/asset_manager/README.md b/x-pack/plugins/observability_solution/asset_manager/README.md similarity index 100% rename from x-pack/plugins/asset_manager/README.md rename to x-pack/plugins/observability_solution/asset_manager/README.md diff --git a/x-pack/plugins/asset_manager/common/config.ts b/x-pack/plugins/observability_solution/asset_manager/common/config.ts similarity index 100% rename from x-pack/plugins/asset_manager/common/config.ts rename to x-pack/plugins/observability_solution/asset_manager/common/config.ts diff --git a/x-pack/plugins/asset_manager/common/constants_routes.ts b/x-pack/plugins/observability_solution/asset_manager/common/constants_routes.ts similarity index 100% rename from x-pack/plugins/asset_manager/common/constants_routes.ts rename to x-pack/plugins/observability_solution/asset_manager/common/constants_routes.ts diff --git a/x-pack/plugins/asset_manager/common/debug_log.ts b/x-pack/plugins/observability_solution/asset_manager/common/debug_log.ts similarity index 100% rename from x-pack/plugins/asset_manager/common/debug_log.ts rename to x-pack/plugins/observability_solution/asset_manager/common/debug_log.ts diff --git a/x-pack/plugins/asset_manager/common/types_api.ts b/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts similarity index 100% rename from x-pack/plugins/asset_manager/common/types_api.ts rename to x-pack/plugins/observability_solution/asset_manager/common/types_api.ts diff --git a/x-pack/plugins/asset_manager/common/types_client.ts b/x-pack/plugins/observability_solution/asset_manager/common/types_client.ts similarity index 100% rename from x-pack/plugins/asset_manager/common/types_client.ts rename to x-pack/plugins/observability_solution/asset_manager/common/types_client.ts diff --git a/x-pack/plugins/asset_manager/docs/api.md b/x-pack/plugins/observability_solution/asset_manager/docs/api.md similarity index 57% rename from x-pack/plugins/asset_manager/docs/api.md rename to x-pack/plugins/observability_solution/asset_manager/docs/api.md index 60810dce22911..219b73cd69bcd 100644 --- a/x-pack/plugins/asset_manager/docs/api.md +++ b/x-pack/plugins/observability_solution/asset_manager/docs/api.md @@ -171,44 +171,42 @@ TODO: Link to a centralized asset document example that each response can refere Get a list of host assets found within a specified time range. -| Parameter | Type | Required? | Description | -| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- | -| from | datetime string | yes | ISO date string representing the START of the time range being queried | -| to | datetime string | yes | ISO date string representing the END of the time range being queried | -| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/klacabane/kibana/blob/main/x-pack/plugins/asset_manager/common/types_api.ts#L168-L178) | +| Parameter | Type | Required? | Description | +| :-------- | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| from | datetime string | yes | ISO date string representing the START of the time range being queried | +| to | datetime string | yes | ISO date string representing the END of the time range being queried | +| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/main/kibana/blob/main/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts#L168-L178) | **Example** ```js getHosts({ - from: '2023-12-04T09:42:00.000Z', - to: '2023-12-04T09:44:00.000Z', - filters: { - 'cloud.provider': 'gcp' - } -}) + from: '2023-12-04T09:42:00.000Z', + to: '2023-12-04T09:44:00.000Z', + filters: { + 'cloud.provider': 'gcp', + }, +}); ``` **Response** ```json { - "hosts": [ - { - "@timestamp": "2023-12-04T09:42:52.538Z", - "asset.kind": "host", - "asset.id": "gcp-host-2zze1241", - "asset.name": "gcp-host-2zze1241", - "asset.ean": "host:gcp-host-2zze1241", - "cloud.provider": "gcp", - "cloud.instance.id": "235111598995020799", - "cloud.service.name": "GCE", - "cloud.region": "us-central1", - "asset.children": [ - "pod:3ca933f5-effa-47f6-b991-fa1b528cc2e4" - ] - } - ] + "hosts": [ + { + "@timestamp": "2023-12-04T09:42:52.538Z", + "asset.kind": "host", + "asset.id": "gcp-host-2zze1241", + "asset.name": "gcp-host-2zze1241", + "asset.ean": "host:gcp-host-2zze1241", + "cloud.provider": "gcp", + "cloud.instance.id": "235111598995020799", + "cloud.service.name": "GCE", + "cloud.region": "us-central1", + "asset.children": ["pod:3ca933f5-effa-47f6-b991-fa1b528cc2e4"] + } + ] } ``` @@ -216,36 +214,36 @@ getHosts({ Get a list of service assets found within a specified time range. -| Parameter | Type | Required? | Description | -| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- | -| from | datetime string | yes | ISO date string representing the START of the time range being queried | -| to | datetime string | yes | ISO date string representing the END of the time range being queried | -| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/klacabane/kibana/blob/main/x-pack/plugins/asset_manager/common/types_api.ts#L168-L178) | +| Parameter | Type | Required? | Description | +| :-------- | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| from | datetime string | yes | ISO date string representing the START of the time range being queried | +| to | datetime string | yes | ISO date string representing the END of the time range being queried | +| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/main/kibana/blob/main/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts#L168-L178) | **Example** ```js getServices({ - from: '2023-12-04T09:42:00.000Z', - to: '2023-12-04T09:44:00.000Z' -}) + from: '2023-12-04T09:42:00.000Z', + to: '2023-12-04T09:44:00.000Z', +}); ``` **Response** ```json { - "services": [ - { - "@timestamp": "2023-12-03T09:44:00.000Z", - "asset.kind": "service", - "asset.id": "adservice", - "asset.ean": "service:adservice", - "asset.parents": [ - "container:50041db622002301a71b15e3c8468aa2b0cdb716b2ebd3091e20975580a397ae" - ] - } - ] + "services": [ + { + "@timestamp": "2023-12-03T09:44:00.000Z", + "asset.kind": "service", + "asset.id": "adservice", + "asset.ean": "service:adservice", + "asset.parents": [ + "container:50041db622002301a71b15e3c8468aa2b0cdb716b2ebd3091e20975580a397ae" + ] + } + ] } ``` @@ -253,39 +251,35 @@ getServices({ Get a list of container assets found within a specified time range. -| Parameter | Type | Required? | Description | -| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- | -| from | datetime string | yes | ISO date string representing the START of the time range being queried | -| to | datetime string | yes | ISO date string representing the END of the time range being queried | -| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/klacabane/kibana/blob/main/x-pack/plugins/asset_manager/common/types_api.ts#L168-L178) | +| Parameter | Type | Required? | Description | +| :-------- | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| from | datetime string | yes | ISO date string representing the START of the time range being queried | +| to | datetime string | yes | ISO date string representing the END of the time range being queried | +| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/main/kibana/blob/main/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts#L168-L178) | **Example** ```js getContainers({ - from: '2023-12-04T09:42:00.000Z', - to: '2023-12-04T09:44:00.000Z' -}) + from: '2023-12-04T09:42:00.000Z', + to: '2023-12-04T09:44:00.000Z', +}); ``` **Response** ```json { - "containers": [ - { - "@timestamp": "2023-12-03T09:42:11.427Z", - "asset.kind": "container", - "asset.id": "040744a58fdbdf9a7d628c4e71842301ccc3ed54a1efa8ff47747af251e5896c", - "asset.ean": "container:040744a58fdbdf9a7d628c4e71842301ccc3ed54a1efa8ff47747af251e5896c", - "asset.parents": [ - "pod:928db0ae-2b63-48f3-8725-a8ddc490d69e" - ], - "asset.references": [ - "host:gcp-host-2zze1241" - ] - } - ] + "containers": [ + { + "@timestamp": "2023-12-03T09:42:11.427Z", + "asset.kind": "container", + "asset.id": "040744a58fdbdf9a7d628c4e71842301ccc3ed54a1efa8ff47747af251e5896c", + "asset.ean": "container:040744a58fdbdf9a7d628c4e71842301ccc3ed54a1efa8ff47747af251e5896c", + "asset.parents": ["pod:928db0ae-2b63-48f3-8725-a8ddc490d69e"], + "asset.references": ["host:gcp-host-2zze1241"] + } + ] } ``` @@ -293,37 +287,35 @@ getContainers({ Get a list of pod assets found within a specified time range. -| Parameter | Type | Required? | Description | -| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- | -| from | datetime string | yes | ISO date string representing the START of the time range being queried | -| to | datetime string | yes | ISO date string representing the END of the time range being queried | -| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/klacabane/kibana/blob/main/x-pack/plugins/asset_manager/common/types_api.ts#L168-L178) | +| Parameter | Type | Required? | Description | +| :-------- | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| from | datetime string | yes | ISO date string representing the START of the time range being queried | +| to | datetime string | yes | ISO date string representing the END of the time range being queried | +| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/main/kibana/blob/main/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts#L168-L178) | **Example** ```js getPods({ - from: '2023-12-04T09:42:00.000Z', - to: '2023-12-04T09:44:00.000Z' -}) + from: '2023-12-04T09:42:00.000Z', + to: '2023-12-04T09:44:00.000Z', +}); ``` **Response** ```json { - "pods": [ - { - "@timestamp": "2023-12-03T09:42:14.680Z", - "asset.kind": "pod", - "asset.id": "00b2bad4-b878-4647-aa00-d8b24c9216f1", - "asset.ean": "pod:00b2bad4-b878-4647-aa00-d8b24c9216f1", - "asset.parents": [ - "host:gcp-host-2zze1241" - ], - "cloud.provider": "gcp" - } - ] + "pods": [ + { + "@timestamp": "2023-12-03T09:42:14.680Z", + "asset.kind": "pod", + "asset.id": "00b2bad4-b878-4647-aa00-d8b24c9216f1", + "asset.ean": "pod:00b2bad4-b878-4647-aa00-d8b24c9216f1", + "asset.parents": ["host:gcp-host-2zze1241"], + "cloud.provider": "gcp" + } + ] } ``` @@ -331,48 +323,46 @@ getPods({ Get a list of service assets found within a specified time range, sorted by timestamp desc. -| Parameter | Type | Required? | Description | -| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- | -| from | datetime string | yes | ISO date string representing the START of the time range being queried | -| to | datetime string | yes | ISO date string representing the END of the time range being queried | -| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/klacabane/kibana/blob/main/x-pack/plugins/asset_manager/common/types_api.ts#L168-L178) | +| Parameter | Type | Required? | Description | +| :-------- | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| from | datetime string | yes | ISO date string representing the START of the time range being queried | +| to | datetime string | yes | ISO date string representing the END of the time range being queried | +| filters | object | no | key/value pairs filtering the assets returned. See [supported filters](https://github.com/main/kibana/blob/main/x-pack/plugins/observability_solution/asset_manager/common/types_api.ts#L168-L178) | **Example** ```js getAssets({ - from: '2023-12-04T09:42:00.000Z', - to: '2023-12-04T09:44:00.000Z' -}) + from: '2023-12-04T09:42:00.000Z', + to: '2023-12-04T09:44:00.000Z', +}); ``` **Response** ```json { - "assets": [ - { - "@timestamp": "2023-12-03T09:44:00.000Z", - "asset.kind": "service", - "asset.id": "adservice", - "asset.ean": "service:adservice", - "asset.parents": [ - "container:50041db622002301a71b15e3c8468aa2b0cdb716b2ebd3091e20975580a397ae" - ] - }, - { - "@timestamp": "2023-12-04T09:42:52.538Z", - "asset.kind": "host", - "asset.id": "gcp-host-2zze1241", - "asset.name": "gcp-host-2zze1241", - "asset.ean": "host:gcp-host-2zze1241", - "cloud.provider": "gcp", - "cloud.instance.id": "235111598995020799", - "cloud.region": "us-central1", - "asset.children": [ - "pod:3ca933f5-effa-47f6-b991-fa1b528cc2e4" - ] - } - ] + "assets": [ + { + "@timestamp": "2023-12-03T09:44:00.000Z", + "asset.kind": "service", + "asset.id": "adservice", + "asset.ean": "service:adservice", + "asset.parents": [ + "container:50041db622002301a71b15e3c8468aa2b0cdb716b2ebd3091e20975580a397ae" + ] + }, + { + "@timestamp": "2023-12-04T09:42:52.538Z", + "asset.kind": "host", + "asset.id": "gcp-host-2zze1241", + "asset.name": "gcp-host-2zze1241", + "asset.ean": "host:gcp-host-2zze1241", + "cloud.provider": "gcp", + "cloud.instance.id": "235111598995020799", + "cloud.region": "us-central1", + "asset.children": ["pod:3ca933f5-effa-47f6-b991-fa1b528cc2e4"] + } + ] } ``` diff --git a/x-pack/plugins/asset_manager/docs/development.md b/x-pack/plugins/observability_solution/asset_manager/docs/development.md similarity index 100% rename from x-pack/plugins/asset_manager/docs/development.md rename to x-pack/plugins/observability_solution/asset_manager/docs/development.md diff --git a/x-pack/plugins/asset_manager/docs/rest_deprecated.md b/x-pack/plugins/observability_solution/asset_manager/docs/rest_deprecated.md similarity index 100% rename from x-pack/plugins/asset_manager/docs/rest_deprecated.md rename to x-pack/plugins/observability_solution/asset_manager/docs/rest_deprecated.md diff --git a/x-pack/plugins/asset_manager/docs/schema/index.md b/x-pack/plugins/observability_solution/asset_manager/docs/schema/index.md similarity index 100% rename from x-pack/plugins/asset_manager/docs/schema/index.md rename to x-pack/plugins/observability_solution/asset_manager/docs/schema/index.md diff --git a/x-pack/plugins/asset_manager/jest.config.js b/x-pack/plugins/observability_solution/asset_manager/jest.config.js similarity index 52% rename from x-pack/plugins/asset_manager/jest.config.js rename to x-pack/plugins/observability_solution/asset_manager/jest.config.js index d54e474b86ff4..3f091dd5109b3 100644 --- a/x-pack/plugins/asset_manager/jest.config.js +++ b/x-pack/plugins/observability_solution/asset_manager/jest.config.js @@ -7,11 +7,12 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../..', - roots: ['/x-pack/plugins/asset_manager'], - coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/asset_manager', + rootDir: '../../../..', + roots: ['/x-pack/plugins/observability_solution/asset_manager'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/observability_solution/asset_manager', coverageReporters: ['text', 'html'], collectCoverageFrom: [ - '/x-pack/plugins/asset_manager/{common,public,server}/**/*.{js,ts,tsx}', + '/x-pack/plugins/observability_solution/asset_manager/{common,public,server}/**/*.{js,ts,tsx}', ], }; diff --git a/x-pack/plugins/asset_manager/kibana.jsonc b/x-pack/plugins/observability_solution/asset_manager/kibana.jsonc similarity index 100% rename from x-pack/plugins/asset_manager/kibana.jsonc rename to x-pack/plugins/observability_solution/asset_manager/kibana.jsonc diff --git a/x-pack/plugins/asset_manager/public/index.ts b/x-pack/plugins/observability_solution/asset_manager/public/index.ts similarity index 100% rename from x-pack/plugins/asset_manager/public/index.ts rename to x-pack/plugins/observability_solution/asset_manager/public/index.ts diff --git a/x-pack/plugins/asset_manager/public/lib/public_assets_client.test.ts b/x-pack/plugins/observability_solution/asset_manager/public/lib/public_assets_client.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/public/lib/public_assets_client.test.ts rename to x-pack/plugins/observability_solution/asset_manager/public/lib/public_assets_client.test.ts diff --git a/x-pack/plugins/asset_manager/public/lib/public_assets_client.ts b/x-pack/plugins/observability_solution/asset_manager/public/lib/public_assets_client.ts similarity index 100% rename from x-pack/plugins/asset_manager/public/lib/public_assets_client.ts rename to x-pack/plugins/observability_solution/asset_manager/public/lib/public_assets_client.ts diff --git a/x-pack/plugins/asset_manager/public/plugin.ts b/x-pack/plugins/observability_solution/asset_manager/public/plugin.ts similarity index 100% rename from x-pack/plugins/asset_manager/public/plugin.ts rename to x-pack/plugins/observability_solution/asset_manager/public/plugin.ts diff --git a/x-pack/plugins/asset_manager/public/types.ts b/x-pack/plugins/observability_solution/asset_manager/public/types.ts similarity index 100% rename from x-pack/plugins/asset_manager/public/types.ts rename to x-pack/plugins/observability_solution/asset_manager/public/types.ts diff --git a/x-pack/plugins/asset_manager/server/constants.ts b/x-pack/plugins/observability_solution/asset_manager/server/constants.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/constants.ts rename to x-pack/plugins/observability_solution/asset_manager/server/constants.ts diff --git a/x-pack/plugins/asset_manager/server/index.ts b/x-pack/plugins/observability_solution/asset_manager/server/index.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/index.ts rename to x-pack/plugins/observability_solution/asset_manager/server/index.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/containers/get_containers.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/containers/get_containers.test.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/containers/get_containers.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/containers/get_containers.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/hosts/get_hosts.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/hosts/get_hosts.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/hosts/get_hosts.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/hosts/get_hosts.test.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/hosts/get_hosts.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/hosts/get_hosts.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/hosts/get_hosts.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/hosts/get_hosts.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/pods/get_pods.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/pods/get_pods.test.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/pods/get_pods.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/pods/get_pods.ts diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/services/get_services.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/services/get_services.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/accessors/services/get_services.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/accessors/services/get_services.ts diff --git a/x-pack/plugins/asset_manager/server/lib/asset_client.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/asset_client.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client.test.ts diff --git a/x-pack/plugins/asset_manager/server/lib/asset_client.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/asset_client.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client.ts diff --git a/x-pack/plugins/asset_manager/server/lib/asset_client_types.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client_types.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/asset_client_types.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/asset_client_types.ts diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/containers.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/containers.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/collectors/containers.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/containers.ts diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/hosts.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/hosts.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/collectors/hosts.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/hosts.ts diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/index.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/index.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/collectors/index.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/index.ts diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/pods.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/pods.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/collectors/pods.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/pods.ts diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/services.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/services.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/collectors/services.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/collectors/services.ts diff --git a/x-pack/plugins/asset_manager/server/lib/errors.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/errors.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/errors.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/errors.ts diff --git a/x-pack/plugins/asset_manager/server/lib/manage_index_templates.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/manage_index_templates.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/manage_index_templates.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/manage_index_templates.ts diff --git a/x-pack/plugins/asset_manager/server/lib/parse_ean.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/parse_ean.test.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/parse_ean.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/parse_ean.test.ts diff --git a/x-pack/plugins/asset_manager/server/lib/parse_ean.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/parse_ean.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/parse_ean.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/parse_ean.ts diff --git a/x-pack/plugins/asset_manager/server/lib/sample_assets.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/sample_assets.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/sample_assets.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/sample_assets.ts diff --git a/x-pack/plugins/asset_manager/server/lib/utils.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/utils.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/utils.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/utils.ts diff --git a/x-pack/plugins/asset_manager/server/lib/validators/validate_date_range.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/validators/validate_date_range.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/validators/validate_date_range.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/validators/validate_date_range.ts diff --git a/x-pack/plugins/asset_manager/server/lib/validators/validation_error.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/validators/validation_error.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/validators/validation_error.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/validators/validation_error.ts diff --git a/x-pack/plugins/asset_manager/server/lib/write_assets.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/write_assets.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/lib/write_assets.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/write_assets.ts diff --git a/x-pack/plugins/asset_manager/server/plugin.ts b/x-pack/plugins/observability_solution/asset_manager/server/plugin.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/plugin.ts rename to x-pack/plugins/observability_solution/asset_manager/server/plugin.ts diff --git a/x-pack/plugins/asset_manager/server/routes/assets/containers.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/assets/containers.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/assets/containers.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/assets/containers.ts diff --git a/x-pack/plugins/asset_manager/server/routes/assets/hosts.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/assets/hosts.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/assets/hosts.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/assets/hosts.ts diff --git a/x-pack/plugins/asset_manager/server/routes/assets/index.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/assets/index.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/assets/index.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/assets/index.ts diff --git a/x-pack/plugins/asset_manager/server/routes/assets/pods.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/assets/pods.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/assets/pods.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/assets/pods.ts diff --git a/x-pack/plugins/asset_manager/server/routes/assets/services.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/assets/services.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/assets/services.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/assets/services.ts diff --git a/x-pack/plugins/asset_manager/server/routes/index.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/index.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/index.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/index.ts diff --git a/x-pack/plugins/asset_manager/server/routes/ping.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/ping.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/ping.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/ping.ts diff --git a/x-pack/plugins/asset_manager/server/routes/sample_assets.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/sample_assets.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/sample_assets.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/sample_assets.ts diff --git a/x-pack/plugins/asset_manager/server/routes/types.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/types.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/types.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/types.ts diff --git a/x-pack/plugins/asset_manager/server/routes/utils.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/utils.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/routes/utils.ts rename to x-pack/plugins/observability_solution/asset_manager/server/routes/utils.ts diff --git a/x-pack/plugins/asset_manager/server/templates/assets_template.ts b/x-pack/plugins/observability_solution/asset_manager/server/templates/assets_template.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/templates/assets_template.ts rename to x-pack/plugins/observability_solution/asset_manager/server/templates/assets_template.ts diff --git a/x-pack/plugins/asset_manager/server/test_utils.ts b/x-pack/plugins/observability_solution/asset_manager/server/test_utils.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/test_utils.ts rename to x-pack/plugins/observability_solution/asset_manager/server/test_utils.ts diff --git a/x-pack/plugins/asset_manager/server/types.ts b/x-pack/plugins/observability_solution/asset_manager/server/types.ts similarity index 100% rename from x-pack/plugins/asset_manager/server/types.ts rename to x-pack/plugins/observability_solution/asset_manager/server/types.ts diff --git a/x-pack/plugins/asset_manager/tsconfig.json b/x-pack/plugins/observability_solution/asset_manager/tsconfig.json similarity index 90% rename from x-pack/plugins/asset_manager/tsconfig.json rename to x-pack/plugins/observability_solution/asset_manager/tsconfig.json index 231cdfb4648e1..da1095d989afb 100644 --- a/x-pack/plugins/asset_manager/tsconfig.json +++ b/x-pack/plugins/observability_solution/asset_manager/tsconfig.json @@ -1,10 +1,10 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "outDir": "target/types" }, "include": [ - "../../../typings/**/*", + "../../../../typings/**/*", "common/**/*", "server/**/*", "public/**/*", diff --git a/x-pack/plugins/metrics_data_access/README.md b/x-pack/plugins/observability_solution/metrics_data_access/README.md similarity index 100% rename from x-pack/plugins/metrics_data_access/README.md rename to x-pack/plugins/observability_solution/metrics_data_access/README.md diff --git a/x-pack/plugins/metrics_data_access/common/alerting/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/alerting/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/alerting/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/alerting/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/alerting/metrics/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/alerting/metrics/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/alerting/metrics/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/alerting/metrics/types.ts diff --git a/x-pack/plugins/metrics_data_access/common/color_palette.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/color_palette.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/color_palette.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/color_palette.ts diff --git a/x-pack/plugins/metrics_data_access/common/constants.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/constants.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts diff --git a/x-pack/plugins/metrics_data_access/common/http_api/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/http_api/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/http_api/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/http_api/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/http_api/metric_indices.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metric_indices.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/http_api/metric_indices.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metric_indices.ts diff --git a/x-pack/plugins/metrics_data_access/common/http_api/metrics_api.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metrics_api.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/http_api/metrics_api.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metrics_api.ts diff --git a/x-pack/plugins/metrics_data_access/common/http_api/metrics_explorer.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metrics_explorer.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/http_api/metrics_explorer.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/http_api/metrics_explorer.ts diff --git a/x-pack/plugins/metrics_data_access/common/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_read_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_read_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_read_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_read_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_write_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_write_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_write_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/disk_io_write_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/rx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/rx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/rx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/rx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/tx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/tx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/tx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/snapshot/tx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_cpu_utilization.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_cpu_utilization.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_cpu_utilization.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_cpu_utilization.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_diskio_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_diskio_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_diskio_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_diskio_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_network_traffic.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_network_traffic.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_network_traffic.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_ec2/metrics/tsvb/aws_ec2_network_traffic.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_active_transactions.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_active_transactions.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_active_transactions.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_active_transactions.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_connections.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_connections.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_connections.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_connections.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_latency.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_latency.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_latency.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_latency.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_queries_executed.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_queries_executed.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_queries_executed.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/snapshot/rds_queries_executed.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_active_transactions.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_active_transactions.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_active_transactions.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_active_transactions.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_connections.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_connections.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_connections.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_connections.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_cpu_total.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_cpu_total.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_cpu_total.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_cpu_total.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_latency.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_latency.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_latency.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_latency.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_queries_executed.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_queries_executed.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_queries_executed.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_rds/metrics/tsvb/aws_rds_queries_executed.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_bucket_size.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_bucket_size.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_bucket_size.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_bucket_size.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_download_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_download_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_download_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_download_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_number_of_objects.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_number_of_objects.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_number_of_objects.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_number_of_objects.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_total_requests.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_total_requests.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_total_requests.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_total_requests.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_upload_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_upload_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_upload_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/snapshot/s3_upload_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_bucket_size.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_bucket_size.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_bucket_size.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_bucket_size.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_download_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_download_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_download_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_download_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_number_of_objects.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_number_of_objects.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_number_of_objects.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_number_of_objects.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_total_requests.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_total_requests.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_total_requests.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_total_requests.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_upload_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_upload_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_upload_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_s3/metrics/tsvb/aws_s3_upload_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_delayed.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_delayed.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_delayed.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_delayed.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_empty.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_empty.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_empty.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_empty.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_sent.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_sent.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_sent.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_sent.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_visible.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_visible.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_visible.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_messages_visible.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_oldest_message.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_oldest_message.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_oldest_message.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/snapshot/sqs_oldest_message.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_delayed.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_delayed.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_delayed.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_delayed.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_empty.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_empty.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_empty.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_empty.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_sent.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_sent.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_sent.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_sent.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_visible.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_visible.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_visible.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_messages_visible.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_oldest_message.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_oldest_message.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_oldest_message.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/aws_sqs/metrics/tsvb/aws_sqs_oldest_message.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/rx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/rx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/rx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/rx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/tx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/tx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/snapshot/tx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/snapshot/tx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_kernel.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_kernel.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_kernel.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_kernel.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_cpu_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_disk_io_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_disk_io_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_disk_io_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_disk_io_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_diskio_ops.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_diskio_ops.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_diskio_ops.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_diskio_ops.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_cpu_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_cpu_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_cpu_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_cpu_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_memory_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_memory_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_memory_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_memory_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_k8s_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_network_traffic.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_network_traffic.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_network_traffic.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_network_traffic.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/tsvb/container_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/create_tsvb_model.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/create_tsvb_model.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/create_tsvb_model.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/create_tsvb_model.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/disk.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/disk.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/disk.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/disk.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/logs.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/logs.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/logs.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/logs.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/disk.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/disk.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/disk.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/disk.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/host_count.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/host_count.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/host_count.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/host_count.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/log_rate.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/log_rate.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/log_rate.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/log_rate.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/network.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/network.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/formulas/network.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/formulas/network.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_latency.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_latency.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_latency.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_latency.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_space_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_space_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_space_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/disk_space_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/load.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/load.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/load.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/load.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/log_rate.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/log_rate.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/log_rate.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/log_rate.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_free.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_free.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_free.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_free.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_total.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_total.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_total.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/memory_total.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/normalized_load_1m.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/normalized_load_1m.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/normalized_load_1m.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/normalized_load_1m.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/rx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/rx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/rx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/rx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/tx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/tx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/snapshot/tx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/snapshot/tx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_info.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_info.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_info.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_info.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_filesystem.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_filesystem.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_filesystem.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_filesystem.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_load.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_load.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_load.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_load.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_system_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_system_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_system_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/host_system_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/host/metrics/tsvb/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/tsvb/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/node.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/node.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/node.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/charts/node.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/disk.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/disk.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/disk.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/disk.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/pod_capacity.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/pod_capacity.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/pod_capacity.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/formulas/pod_capacity.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/node/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/node/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/cpu.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/cpu.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/cpu.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/cpu.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/memory.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/memory.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/memory.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/memory.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/rx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/rx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/rx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/rx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/tx.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/tx.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/tx.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/snapshot/tx.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_cpu_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_cpu_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_cpu_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_cpu_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_log_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_log_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_log_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_log_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_memory_usage.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_memory_usage.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_memory_usage.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_memory_usage.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_network_traffic.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_network_traffic.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_network_traffic.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_network_traffic.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/kubernetes/pod/metrics/tsvb/pod_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/metrics.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/metrics.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/metrics.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/metrics.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/charts/constants.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/charts/constants.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/required_metrics.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/required_metrics.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/required_metrics.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/required_metrics.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/count.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/count.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/count.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/count.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic_with_interfaces.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic_with_interfaces.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic_with_interfaces.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/network_traffic_with_interfaces.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/rate.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/rate.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/snapshot/rate.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/snapshot/rate.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_overview.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_overview.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_overview.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/aws_overview.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_active_connections.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_active_connections.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_active_connections.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_active_connections.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_hits.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_hits.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_hits.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_hits.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_request_rate.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_request_rate.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_request_rate.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_request_rate.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_requests_per_connection.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_requests_per_connection.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_requests_per_connection.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/metrics/tsvb/nginx_requests_per_connection.ts diff --git a/x-pack/plugins/metrics_data_access/common/inventory_models/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/inventory_models/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/types.ts diff --git a/x-pack/plugins/metrics_data_access/common/metrics_explorer_views/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/metrics_explorer_views/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/metrics_explorer_views/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/metrics_explorer_views/types.ts diff --git a/x-pack/plugins/metrics_data_access/common/runtime_types.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/runtime_types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/runtime_types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/runtime_types.ts diff --git a/x-pack/plugins/metrics_data_access/common/utility_types.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/utility_types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/common/utility_types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/common/utility_types.ts diff --git a/x-pack/plugins/metrics_data_access/jest.config.js b/x-pack/plugins/observability_solution/metrics_data_access/jest.config.js similarity index 64% rename from x-pack/plugins/metrics_data_access/jest.config.js rename to x-pack/plugins/observability_solution/metrics_data_access/jest.config.js index 9c8e01aabd0aa..15e98e0b078f8 100644 --- a/x-pack/plugins/metrics_data_access/jest.config.js +++ b/x-pack/plugins/observability_solution/metrics_data_access/jest.config.js @@ -7,9 +7,10 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../..', - roots: ['/x-pack/plugins/metrics_data_access'], - coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/metrics_data_access', + rootDir: '../../../..', + roots: ['/x-pack/plugins/observability_solution/metrics_data_access'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/observability_solution/metrics_data_access', coverageReporters: ['text', 'html'], collectCoverageFrom: ['/x-pack/plugins/metrics_data/{server}/**/*.test.ts'], }; diff --git a/x-pack/plugins/metrics_data_access/kibana.jsonc b/x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc similarity index 100% rename from x-pack/plugins/metrics_data_access/kibana.jsonc rename to x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc diff --git a/x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/apps/common_providers.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/apps/common_providers.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/apps/common_providers.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/empty_states/index.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/index.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/empty_states/index.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/index.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/empty_states/no_data.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_data.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/empty_states/no_data.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_data.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/empty_states/no_indices.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_indices.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/empty_states/no_indices.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_indices.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/empty_states/no_metric_indices.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_metric_indices.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/empty_states/no_metric_indices.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_metric_indices.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/empty_states/no_remote_cluster.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_remote_cluster.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/empty_states/no_remote_cluster.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/empty_states/no_remote_cluster.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/README.md b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/README.md similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/README.md rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/README.md diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.stories.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.stories.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.stories.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.stories.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.test.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.test.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.test.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.test.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/container_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/create_lazy_container_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/create_lazy_container_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/create_lazy_container_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/create_lazy_container_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/integrated_container_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/integrated_container_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/integrated_container_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/integrated_container_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.test.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/container/use_container_metrics_table.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/create_lazy_host_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/create_lazy_host_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/create_lazy_host_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/create_lazy_host_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.stories.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.stories.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.stories.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.stories.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.test.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.test.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.test.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.test.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/host_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/integrated_host_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/integrated_host_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/integrated_host_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/integrated_host_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.test.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/host/use_host_metrics_table.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/create_lazy_pod_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/create_lazy_pod_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/create_lazy_pod_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/create_lazy_pod_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/integrated_pod_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/integrated_pod_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/integrated_pod_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/integrated_pod_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.stories.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.stories.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.stories.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.stories.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.test.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.test.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.test.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.test.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/pod_metrics_table.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.test.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/pod/use_pod_metrics_table.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_dark.svg b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_dark.svg similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_dark.svg rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_dark.svg diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_light.svg b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_light.svg similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_light.svg rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/assets/no_results_light.svg diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/error_content.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/error_content.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/error_content.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/error_content.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/metrics_node_details_link.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/metrics_node_details_link.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/metrics_node_details_link.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/metrics_node_details_link.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/no_data_content.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/no_data_content.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/no_data_content.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/no_data_content.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/number_cell.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/number_cell.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/number_cell.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/number_cell.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/stepwise_pagination.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/stepwise_pagination.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/stepwise_pagination.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/components/stepwise_pagination.tsx diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/helpers.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/helpers.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/helpers.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/helpers.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.test.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/metrics_to_api_options.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/use_infrastructure_node_metrics.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/use_infrastructure_node_metrics.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/use_infrastructure_node_metrics.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/hooks/use_infrastructure_node_metrics.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/shared/types.ts diff --git a/x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/test_helpers.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/test_helpers.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/components/infrastructure_node_metrics_tables/test_helpers.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/components/infrastructure_node_metrics_tables/test_helpers.ts diff --git a/x-pack/plugins/metrics_data_access/public/hooks/use_kibana.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/hooks/use_kibana.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/hooks/use_kibana.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/hooks/use_kibana.tsx diff --git a/x-pack/plugins/metrics_data_access/public/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/lib/metrics_client.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/lib/metrics_client.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/lib/metrics_client.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/lib/metrics_client.ts diff --git a/x-pack/plugins/metrics_data_access/public/pages/link_to/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/pages/link_to/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/pages/link_to/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/pages/link_to/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/pages/link_to/use_node_details_redirect.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/pages/link_to/use_node_details_redirect.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/pages/link_to/use_node_details_redirect.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/pages/link_to/use_node_details_redirect.ts diff --git a/x-pack/plugins/metrics_data_access/public/plugin.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/plugin.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/plugin.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/plugin.ts diff --git a/x-pack/plugins/metrics_data_access/public/test_utils/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/test_utils/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/test_utils/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/test_utils/index.ts diff --git a/x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/observability_solution/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx similarity index 100% rename from x-pack/plugins/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx rename to x-pack/plugins/observability_solution/metrics_data_access/public/test_utils/use_global_storybook_theme.tsx diff --git a/x-pack/plugins/metrics_data_access/public/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/types.ts diff --git a/x-pack/plugins/metrics_data_access/public/utils/use_tracked_promise.ts b/x-pack/plugins/observability_solution/metrics_data_access/public/utils/use_tracked_promise.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/public/utils/use_tracked_promise.ts rename to x-pack/plugins/observability_solution/metrics_data_access/public/utils/use_tracked_promise.ts diff --git a/x-pack/plugins/metrics_data_access/server/client/client.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/client/client.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/client/client.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/client/client.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/client/client.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/client/client.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/client/client.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/client/client.ts diff --git a/x-pack/plugins/metrics_data_access/server/client/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/client/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/client/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/client/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/client_mock.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/client_mock.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/client_mock.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/client_mock.ts diff --git a/x-pack/plugins/metrics_data_access/server/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/adapters/framework/adapter_types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/adapters/framework/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/adapters/framework/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/kibana_framework_adapter.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/adapters/framework/kibana_framework_adapter.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/kibana_framework_adapter.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/adapters/metrics/adapter_types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/metrics/adapter_types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/adapters/metrics/adapter_types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/metrics/adapter_types.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/adapters/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/adapters/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/create_custom_metrics_aggregations.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/create_custom_metrics_aggregations.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/create_custom_metrics_aggregations.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/create_custom_metrics_aggregations.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/create_search_client.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/create_search_client.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/create_search_client.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/create_search_client.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/constants.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/constants.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/constants.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/constants.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/convert_buckets_to_metrics_series.test.ts.snap b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/convert_buckets_to_metrics_series.test.ts.snap similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/convert_buckets_to_metrics_series.test.ts.snap rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/convert_buckets_to_metrics_series.test.ts.snap diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_metrics_aggregations.test.ts.snap b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_metrics_aggregations.test.ts.snap similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_metrics_aggregations.test.ts.snap rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/__snapshots__/create_metrics_aggregations.test.ts.snap diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_auto.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_bucket_size.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_bucket_size.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_bucket_size.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/calculate_bucket_size.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/interval_regex.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_bucket_size/unit_to_seconds.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_date_histogram_offset.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_interval.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_interval.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/calculate_interval.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/calculate_interval.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/convert_buckets_to_metrics_series.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_aggregations.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_aggregations.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_aggregations.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_aggregations.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_aggregations.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_aggregations.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_aggregations.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_aggregations.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/lib/create_metrics_aggregations.ts diff --git a/x-pack/plugins/metrics_data_access/server/lib/metrics/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/lib/metrics/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/lib/metrics/types.ts diff --git a/x-pack/plugins/metrics_data_access/server/plugin.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/plugin.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/plugin.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/plugin.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metric_indices/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metric_indices/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metric_indices/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metric_indices/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_metric_to_metrics_api_metric.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/convert_request_to_metrics_api_options.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/get_dataset_for_field.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/get_dataset_for_field.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/get_dataset_for_field.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/get_dataset_for_field.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/query_total_grouping.test.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/query_total_grouping.test.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/query_total_grouping.test.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/query_total_grouping.test.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/query_total_groupings.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/query_total_groupings.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/query_total_groupings.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/query_total_groupings.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/transform_series.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/transform_series.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/metrics_explorer/lib/transform_series.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/metrics_explorer/lib/transform_series.ts diff --git a/x-pack/plugins/metrics_data_access/server/routes/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/routes/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/routes/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/routes/types.ts diff --git a/x-pack/plugins/metrics_data_access/server/saved_objects/metrics_data_source/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/saved_objects/metrics_data_source/index.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/saved_objects/metrics_data_source/index.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/saved_objects/metrics_data_source/index.ts diff --git a/x-pack/plugins/metrics_data_access/server/types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/types.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/types.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/types.ts diff --git a/x-pack/plugins/metrics_data_access/server/utils/calculate_metric_interval.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/utils/calculate_metric_interval.ts similarity index 100% rename from x-pack/plugins/metrics_data_access/server/utils/calculate_metric_interval.ts rename to x-pack/plugins/observability_solution/metrics_data_access/server/utils/calculate_metric_interval.ts diff --git a/x-pack/plugins/metrics_data_access/tsconfig.json b/x-pack/plugins/observability_solution/metrics_data_access/tsconfig.json similarity index 87% rename from x-pack/plugins/metrics_data_access/tsconfig.json rename to x-pack/plugins/observability_solution/metrics_data_access/tsconfig.json index 5f387443ed53a..7c6c2e1bd3d95 100644 --- a/x-pack/plugins/metrics_data_access/tsconfig.json +++ b/x-pack/plugins/observability_solution/metrics_data_access/tsconfig.json @@ -1,9 +1,9 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "outDir": "target/types" }, - "include": ["../../../typings/**/*", "server/**/*", "common/**/*", "public/**/*"], + "include": ["../../../../typings/**/*", "server/**/*", "common/**/*", "public/**/*"], "exclude": ["target/**/*"], "kbn_references": [ "@kbn/core", diff --git a/yarn.lock b/yarn.lock index 1f7dd83962b44..746867f15231c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3242,7 +3242,7 @@ version "0.0.0" uid "" -"@kbn/assetManager-plugin@link:x-pack/plugins/asset_manager": +"@kbn/assetManager-plugin@link:x-pack/plugins/observability_solution/asset_manager": version "0.0.0" uid "" @@ -5258,7 +5258,7 @@ version "0.0.0" uid "" -"@kbn/metrics-data-access-plugin@link:x-pack/plugins/metrics_data_access": +"@kbn/metrics-data-access-plugin@link:x-pack/plugins/observability_solution/metrics_data_access": version "0.0.0" uid "" From 6910e0c7d7a02128c2ff73a7a6fed838d9f56270 Mon Sep 17 00:00:00 2001 From: Yngrid Coello Date: Tue, 30 Apr 2024 14:39:15 +0200 Subject: [PATCH 036/104] [Dataset quality] Integration non-default dataset is now marked as part of the integration (#182097) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes https://github.com/elastic/kibana/issues/181542 ## 📝 Summary This PR uses`IndicesDataStream` metadata info to determine whether a non-default dataset belongs to an integration or not ## 🎥 Demo ### Before changes https://github.com/elastic/kibana/assets/1313018/23fbbb9d-ae52-4e30-b525-8176f89d6462 ### After changes https://github.com/elastic/kibana/assets/1313018/5423dba2-fbcf-47b4-87b7-2987f5a1f6d2 --------- Co-authored-by: mohamedhamed-ahmed --- .../data_streams_stats/data_stream_stat.ts | 8 +- .../common/data_streams_stats/types.ts | 3 +- .../hooks/use_dataset_quality_filters.tsx | 53 +++++----- .../data_streams_stats_client.ts | 3 +- .../src/state_machine.ts | 2 +- .../dataset_quality_controller/src/types.ts | 3 +- .../summary_panel/src/state_machine.ts | 5 +- .../public/utils/generate_datasets.test.ts | 97 +++++++++++++------ .../public/utils/generate_datasets.ts | 64 +++++++----- 9 files changed, 151 insertions(+), 87 deletions(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts index f3b68e2c1c2a0..0cf0a40b1b45b 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts @@ -65,10 +65,10 @@ export class DataStreamStat { public static fromDegradedDocStat({ degradedDocStat, - integrationMap, + datasetIntegrationMap, }: { degradedDocStat: DegradedDocsStat; - integrationMap: Record; + datasetIntegrationMap: Record; }) { const { type, dataset, namespace } = indexNameToDataStreamParts(degradedDocStat.dataset); @@ -76,9 +76,9 @@ export class DataStreamStat { rawName: degradedDocStat.dataset, type, name: dataset, - title: integrationMap[dataset]?.title || dataset, + title: datasetIntegrationMap[dataset]?.title || dataset, namespace, - integration: integrationMap[dataset]?.integration, + integration: datasetIntegrationMap[dataset]?.integration, degradedDocs: { percentage: degradedDocStat.percentage, count: degradedDocStat.count, diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts index 66fbffd452dc6..0c9456c2d7257 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts @@ -6,7 +6,6 @@ */ import { APIClientRequestParamsOf, APIReturnType } from '../rest'; -import { DataStreamStat } from './data_stream_stat'; export type GetDataStreamsStatsParams = APIClientRequestParamsOf<`GET /internal/dataset_quality/data_streams/stats`>['params']; @@ -14,7 +13,7 @@ export type GetDataStreamsStatsQuery = GetDataStreamsStatsParams['query']; export type GetDataStreamsStatsResponse = APIReturnType<`GET /internal/dataset_quality/data_streams/stats`>; export type DataStreamStatType = GetDataStreamsStatsResponse['dataStreamsStats'][0]; -export type DataStreamStatServiceResponse = DataStreamStat[]; +export type DataStreamStatServiceResponse = DataStreamStatType[]; export type GetIntegrationsParams = APIClientRequestParamsOf<`GET /internal/dataset_quality/integrations`>['params']; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_filters.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_filters.tsx index d6eccbbe545f2..a4d7be4fca46e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_filters.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_filters.tsx @@ -36,26 +36,22 @@ export const useDatasetQualityFilters = () => { interface Filters { namespaces: string[]; qualities: QualityIndicators[]; - integrations: Integration[]; - hasNoneIntegration: boolean; + filteredIntegrations: string[]; } const datasets = useSelector(service, (state) => state.context.datasets); - const { namespaces, qualities, integrations } = useMemo( + const integrations = useSelector(service, (state) => state.context.integrations); + const { namespaces, qualities, filteredIntegrations } = useMemo( () => datasets.reduce( - (acc: Filters, dataset) => { - acc.namespaces.push(dataset.namespace); - acc.qualities.push(dataset.degradedDocs.quality); - if (dataset.integration) { - acc.integrations.push(dataset.integration); - } else if (!acc.hasNoneIntegration) { - acc.integrations.push(Integration.create({ name: 'none', title: 'None' })); - acc.hasNoneIntegration = true; - } - return acc; - }, - { namespaces: [], qualities: [], integrations: [], hasNoneIntegration: false } + (acc: Filters, dataset) => ({ + namespaces: [...new Set([...acc.namespaces, dataset.namespace])], + qualities: [...new Set([...acc.qualities, dataset.degradedDocs.quality])], + filteredIntegrations: [ + ...new Set([...acc.filteredIntegrations, dataset.integration?.name ?? 'none']), + ], + }), + { namespaces: [], qualities: [], filteredIntegrations: [] } ), [datasets] ); @@ -100,15 +96,24 @@ export const useDatasetQualityFilters = () => { [service, timeRange] ); - const integrationItems: IntegrationItem[] = useMemo( - () => - integrations.map((integration) => ({ - ...integration, - label: integration.title, - checked: selectedIntegrations.includes(integration.name) ? 'on' : undefined, - })), - [integrations, selectedIntegrations] - ); + const integrationItems: IntegrationItem[] = useMemo(() => { + const integrationsMap = + integrations?.reduce( + (acc, integration) => ({ + ...acc, + [integration.name]: integration, + }), + {} as { [key: string]: Integration } + ) ?? {}; + + integrationsMap.none = Integration.create({ name: 'none', title: 'None' }); + + return filteredIntegrations.map((name) => ({ + ...integrationsMap[name], + label: integrationsMap[name]?.title, + checked: selectedIntegrations.includes(name) ? 'on' : undefined, + })); + }, [integrations, filteredIntegrations, selectedIntegrations]); const onIntegrationsChange = useCallback( (newIntegrationItems: IntegrationItem[]) => { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts index 2fc2b388f3a8d..d908c8665c1f4 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts @@ -27,7 +27,6 @@ import { GetIntegrationsParams, IntegrationsResponse, } from '../../../common/data_streams_stats'; -import { DataStreamStat } from '../../../common/data_streams_stats/data_stream_stat'; import { IDataStreamsStatsClient } from './types'; export class DataStreamsStatsClient implements IDataStreamsStatsClient { @@ -50,7 +49,7 @@ export class DataStreamsStatsClient implements IDataStreamsStatsClient { new GetDataStreamsStatsError(`Failed to decode data streams stats response: ${message}`) )(response); - return dataStreamsStats.map(DataStreamStat.create); + return dataStreamsStats; } public async getDataStreamsDegradedStats(params: GetDataStreamsDegradedDocsStatsQuery) { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts index bc60bad709a7b..7d54e268bb5df 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts @@ -8,13 +8,13 @@ import { IToasts } from '@kbn/core/public'; import { getDateISORange } from '@kbn/timerange'; import { assign, createMachine, DoneInvokeEvent, InterpreterFrom } from 'xstate'; +import { DataStreamStat } from '../../../../common/api_types'; import { Integration } from '../../../../common/data_streams_stats/integration'; import { IDataStreamDetailsClient } from '../../../services/data_stream_details'; import { DashboardType, DataStreamSettings, DataStreamDetails, - DataStreamStat, GetDataStreamsStatsQuery, GetIntegrationsParams, } from '../../../../common/data_streams_stats'; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts index d4c1236329f2b..10c08f8fa0bfc 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts @@ -19,6 +19,7 @@ import { DataStreamStatServiceResponse, IntegrationsResponse, DataStreamStat, + DataStreamStatType, } from '../../../../common/data_streams_stats'; export type FlyoutDataset = Omit< @@ -68,7 +69,7 @@ export interface WithFilters { } export interface WithDataStreamStats { - dataStreamStats: DataStreamStat[]; + dataStreamStats: DataStreamStatType[]; } export interface WithDegradedDocs { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/summary_panel/src/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/summary_panel/src/state_machine.ts index 55daf83af13bf..ae5e414c192fb 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/summary_panel/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/summary_panel/src/state_machine.ts @@ -8,6 +8,7 @@ import { IToasts } from '@kbn/core/public'; import { getDateISORange } from '@kbn/timerange'; import { assign, createMachine, DoneInvokeEvent, InterpreterFrom } from 'xstate'; +import { DataStreamStat } from '../../../../common/data_streams_stats/data_stream_stat'; import { DEFAULT_TIME_RANGE } from '../../../../common/constants'; import { IDataStreamsStatsClient } from '../../../services/data_streams_stats'; import { filterInactiveDatasets } from '../../../utils/filter_inactive_datasets'; @@ -228,7 +229,9 @@ export const createDatasetsSummaryPanelStateMachine = ({ }, loadDatasetsActivity: async (_context) => { const dataStreamStats = await dataStreamStatsClient.getDataStreamsStats(); - const activeDataStreams = filterInactiveDatasets({ datasets: dataStreamStats }); + const activeDataStreams = filterInactiveDatasets({ + datasets: dataStreamStats.map(DataStreamStat.create), + }); return { total: dataStreamStats.length, active: activeDataStreams.length, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts index 0db27c57dfc1f..9b9a007f0c54b 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts @@ -6,9 +6,9 @@ */ import { indexNameToDataStreamParts } from '../../common/utils'; -import { DataStreamStat } from '../../common/data_streams_stats/data_stream_stat'; import { Integration } from '../../common/data_streams_stats/integration'; import { generateDatasets } from './generate_datasets'; +import { DataStreamStatType } from '../../common/data_streams_stats/types'; describe('generateDatasets', () => { const integrations: Integration[] = [ @@ -34,36 +34,19 @@ describe('generateDatasets', () => { }, ]; - const dataStreamStats: DataStreamStat[] = [ + const dataStreamStats: DataStreamStatType[] = [ { - name: 'system.application', - title: 'system.application', - type: 'logs', - namespace: 'default', + name: 'logs-system.application-default', lastActivity: 1712911241117, size: '82.1kb', sizeBytes: 84160, - rawName: 'logs-system.application-default', - degradedDocs: { - percentage: 0, - count: 0, - quality: 'good', - }, + integration: 'system', }, { - name: 'synth', - title: 'synth', - type: 'logs', - namespace: 'default', + name: 'logs-synth-default', lastActivity: 1712911241117, - rawName: 'logs-synth-default', size: '62.5kb', sizeBytes: 64066, - degradedDocs: { - percentage: 0, - count: 0, - quality: 'good', - }, }, ]; @@ -88,16 +71,31 @@ describe('generateDatasets', () => { expect(datasets).toEqual([ { ...dataStreamStats[0], - title: integrations[0].datasets[dataStreamStats[0].name], + name: indexNameToDataStreamParts(dataStreamStats[0].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[0].name).namespace, + title: + integrations[0].datasets[indexNameToDataStreamParts(dataStreamStats[0].name).dataset], + type: indexNameToDataStreamParts(dataStreamStats[0].name).type, + rawName: dataStreamStats[0].name, integration: integrations[0], degradedDocs: { percentage: degradedDocs[0].percentage, count: degradedDocs[0].count, - quality: 'good', + quality: degradedDocs[0].quality, }, }, { ...dataStreamStats[1], + name: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[1].name).namespace, + title: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + type: indexNameToDataStreamParts(dataStreamStats[1].name).type, + rawName: dataStreamStats[1].name, + degradedDocs: { + count: 0, + percentage: 0, + quality: 'good', + }, }, ]); }); @@ -120,7 +118,7 @@ describe('generateDatasets', () => { degradedDocs: { percentage: degradedDocs[0].percentage, count: degradedDocs[0].count, - quality: 'good', + quality: degradedDocs[0].quality, }, }, { @@ -136,7 +134,7 @@ describe('generateDatasets', () => { degradedDocs: { percentage: degradedDocs[1].percentage, count: degradedDocs[1].count, - quality: 'poor', + quality: degradedDocs[1].quality, }, }, ]); @@ -148,20 +146,61 @@ describe('generateDatasets', () => { expect(datasets).toEqual([ { ...dataStreamStats[0], - title: integrations[0].datasets[dataStreamStats[0].name], + name: indexNameToDataStreamParts(dataStreamStats[0].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[0].name).namespace, + title: + integrations[0].datasets[indexNameToDataStreamParts(dataStreamStats[0].name).dataset], + type: indexNameToDataStreamParts(dataStreamStats[0].name).type, + rawName: dataStreamStats[0].name, integration: integrations[0], degradedDocs: { percentage: degradedDocs[0].percentage, count: degradedDocs[0].count, - quality: 'good', + quality: degradedDocs[0].quality, }, }, { ...dataStreamStats[1], + name: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[1].name).namespace, + title: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + type: indexNameToDataStreamParts(dataStreamStats[1].name).type, + rawName: dataStreamStats[1].name, degradedDocs: { percentage: degradedDocs[1].percentage, count: degradedDocs[1].count, - quality: 'poor', + quality: degradedDocs[1].quality, + }, + }, + ]); + }); + + it('merges integration information with dataStreamStats when dataset is not an integration default one', () => { + const dataset = 'logs-system.custom-default'; + + const nonDefaultDataset = { + name: dataset, + lastActivity: 1712911241117, + size: '82.1kb', + sizeBytes: 84160, + integration: 'system', + }; + + const datasets = generateDatasets([nonDefaultDataset], undefined, integrations); + + expect(datasets).toEqual([ + { + ...nonDefaultDataset, + title: indexNameToDataStreamParts(dataset).dataset, + name: indexNameToDataStreamParts(dataset).dataset, + namespace: indexNameToDataStreamParts(dataset).namespace, + type: indexNameToDataStreamParts(dataset).type, + rawName: nonDefaultDataset.name, + integration: integrations[0], + degradedDocs: { + count: 0, + percentage: 0, + quality: 'good', }, }, ]); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts index 3d592794413b0..e2f85d8846c99 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts @@ -5,40 +5,52 @@ * 2.0. */ +import { DataStreamStatType } from '../../common/data_streams_stats/types'; import { mapPercentageToQuality } from '../../common/utils'; import { Integration } from '../../common/data_streams_stats/integration'; import { DataStreamStat } from '../../common/data_streams_stats/data_stream_stat'; import { DegradedDocsStat } from '../../common/data_streams_stats/malformed_docs_stat'; export function generateDatasets( - dataStreamStats: DataStreamStat[] = [], + dataStreamStats: DataStreamStatType[] = [], degradedDocStats: DegradedDocsStat[] = [], integrations: Integration[] -) { +): DataStreamStat[] { if (!dataStreamStats.length && !integrations.length) { return []; } - const integrationMap: Record = - integrations.reduce((integrationMapAcc, integration) => { + const { + datasetIntegrationMap, + integrationsMap, + }: { + datasetIntegrationMap: Record; + integrationsMap: Record; + } = integrations.reduce( + (acc, integration) => { return { - ...integrationMapAcc, - ...Object.keys(integration.datasets).reduce( - (datasetsAcc, dataset) => - Object.assign(datasetsAcc, { - [dataset]: { - integration, - title: integration.datasets[dataset], - }, - }), - {} - ), + datasetIntegrationMap: { + ...acc.datasetIntegrationMap, + ...Object.keys(integration.datasets).reduce( + (datasetsAcc, dataset) => + Object.assign(datasetsAcc, { + [dataset]: { + integration, + title: integration.datasets[dataset], + }, + }), + {} + ), + }, + integrationsMap: { ...acc.integrationsMap, [integration.name]: integration }, }; - }, {}); + }, + { datasetIntegrationMap: {}, integrationsMap: {} } + ); if (!dataStreamStats.length) { return degradedDocStats.map((degradedDocStat) => - DataStreamStat.fromDegradedDocStat({ degradedDocStat, integrationMap }) + DataStreamStat.fromDegradedDocStat({ degradedDocStat, datasetIntegrationMap }) ); } @@ -61,10 +73,16 @@ export function generateDatasets( {} ); - return dataStreamStats?.map((dataStream) => ({ - ...dataStream, - title: integrationMap[dataStream.name]?.title || dataStream.title, - integration: integrationMap[dataStream.name]?.integration, - degradedDocs: degradedMap[dataStream.rawName] || dataStream.degradedDocs, - })); + return dataStreamStats?.map((dataStream) => { + const dataset = DataStreamStat.create(dataStream); + + return { + ...dataset, + title: datasetIntegrationMap[dataset.name]?.title || dataset.title, + integration: + datasetIntegrationMap[dataset.name]?.integration ?? + integrationsMap[dataStream.integration ?? ''], + degradedDocs: degradedMap[dataset.rawName] || dataset.degradedDocs, + }; + }); } From bb92dd5b72bd45d11c97dbe998a1d3b131af94ac Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Tue, 30 Apr 2024 14:41:00 +0200 Subject: [PATCH 037/104] [FieldFormatters] Fix Human-readable (precise) formatting (#181391) A fix for the way the human precise formatting is handled when duration formatting is applied. It changes the calculation of the fractional part to be based on seconds. Co-authored-by: Julia Rechkunova --- .../common/converters/duration.test.ts | 232 ++++++++++++++++++ .../common/converters/duration.ts | 94 +++---- 2 files changed, 262 insertions(+), 64 deletions(-) diff --git a/src/plugins/field_formats/common/converters/duration.test.ts b/src/plugins/field_formats/common/converters/duration.test.ts index 52fb64888f5ac..d98abca2d4436 100644 --- a/src/plugins/field_formats/common/converters/duration.test.ts +++ b/src/plugins/field_formats/common/converters/duration.test.ts @@ -216,6 +216,10 @@ describe('Duration Format', () => { outputPrecision: 0, showSuffix: true, fixtures: [ + { + input: 0.1, + output: '100 milliseconds', + }, { input: 600, output: '10 minutes', @@ -231,6 +235,56 @@ describe('Duration Format', () => { ], }); + testCase({ + inputFormat: 'seconds', + outputFormat: 'humanizePrecise', + outputPrecision: 2, + showSuffix: true, + useShortSuffix: false, + fixtures: [ + { + input: -12, + output: '-12.00 seconds', + }, + { + input: -123, + output: '-2.05 minutes', + }, + { + input: 1, + output: '1.00 seconds', + }, + { + input: 12, + output: '12.00 seconds', + }, + { + input: 123, + output: '2.05 minutes', + }, + { + input: 658, + output: '10.97 minutes', + }, + { + input: 1988, + output: '33.13 minutes', + }, + { + input: 3857, + output: '1.07 hours', + }, + { + input: 123292, + output: '1.43 days', + }, + { + input: 923528271, + output: '29.28 years', + }, + ], + }); + testCase({ inputFormat: 'milliseconds', outputFormat: 'humanizePrecise', @@ -242,6 +296,10 @@ describe('Duration Format', () => { input: -123, output: '-123 ms', }, + { + input: -1230, + output: '-1 s', + }, { input: 1, output: '1 ms', @@ -281,6 +339,176 @@ describe('Duration Format', () => { ], }); + testCase({ + inputFormat: 'milliseconds', + outputFormat: 'humanizePrecise', + outputPrecision: 2, + showSuffix: true, + useShortSuffix: true, + fixtures: [ + { + input: 0.5, + output: '0.50 ms', + }, + { + input: -123.5, + output: '-123.50 ms', + }, + { + input: -123, + output: '-123.00 ms', + }, + { + input: 1, + output: '1.00 ms', + }, + { + input: 600, + output: '600.00 ms', + }, + { + input: 30, + output: '30.00 ms', + }, + { + input: 3000, + output: '3.00 s', + }, + { + input: 300000, + output: '5.00 min', + }, + { + input: 30000000, + output: '8.33 h', + }, + { + input: 90000000, + output: '1.04 d', + }, + { + input: 9000000000, + output: '3.47 mon', + }, + { + input: 99999999999, + output: '3.17 y', + }, + ], + }); + + testCase({ + inputFormat: 'seconds', + outputFormat: 'humanizePrecise', + outputPrecision: 2, + showSuffix: true, + fixtures: [ + { + input: 0.5, + output: '500.00 milliseconds', + }, + { + input: 600, + output: '10.00 minutes', + }, + { + input: 30, + output: '30.00 seconds', + }, + { + input: 3000, + output: '50.00 minutes', + }, + { + input: 604800, + output: '1.00 weeks', + }, + // 1 week and 3 and a half days + { + input: 907200, + output: '1.50 weeks', + }, + { + input: 691200, + output: '1.14 weeks', + }, + ], + }); + + testCase({ + inputFormat: 'hours', + outputFormat: 'humanizePrecise', + outputPrecision: 0, + showSuffix: true, + useShortSuffix: true, + fixtures: [ + { + input: 0.5, + output: '30 min', + }, + { + input: 339, + output: '2 w', + }, + ], + }); + + testCase({ + inputFormat: 'hours', + outputFormat: 'humanizePrecise', + outputPrecision: 2, + showSuffix: true, + useShortSuffix: true, + fixtures: [ + { + input: 0.1, + output: '6.00 min', + }, + { + input: 12, + output: '12.00 h', + }, + { + input: 24, + output: '1.00 d', + }, + { + input: 339, + output: '2.02 w', + }, + { + input: 500, + output: '2.98 w', + }, + { + input: 1000, + output: '1.39 mon', + }, + ], + }); + + testCase({ + inputFormat: 'minutes', + outputFormat: 'humanizePrecise', + outputPrecision: 2, + showSuffix: false, + useShortSuffix: false, + fixtures: [ + { + input: 0.1, + output: '6.00 seconds', + }, + { + input: 100.1, + output: '1.67 hours', + }, + { + input: 10750, + output: '1.07 weeks', + }, + ], + }); + testCase({ inputFormat: 'milliseconds', outputFormat: 'humanizePrecise', @@ -289,6 +517,10 @@ describe('Duration Format', () => { useShortSuffix: true, includeSpaceWithSuffix: false, fixtures: [ + { + input: 0.5, + output: '1ms', + }, { input: -123, output: '-123ms', diff --git a/src/plugins/field_formats/common/converters/duration.ts b/src/plugins/field_formats/common/converters/duration.ts index 1ed6ec014ed47..8c9c4e9d33569 100644 --- a/src/plugins/field_formats/common/converters/duration.ts +++ b/src/plugins/field_formats/common/converters/duration.ts @@ -28,35 +28,13 @@ const HUMAN_FRIENDLY = 'humanize'; const HUMAN_FRIENDLY_PRECISE = 'humanizePrecise'; const DEFAULT_OUTPUT_PRECISION = 2; -function parseInputAsDuration(val: number, inputFormat: string) { +function parseInputAsDuration(val: number, inputFormat: string, humanPrecise: boolean) { const ratio = ratioToSeconds[inputFormat] || 1; const kind = ( inputFormat in ratioToSeconds ? 'seconds' : inputFormat ) as unitOfTime.DurationConstructor; - return moment.duration(val * ratio, kind); -} - -function formatInputHumanPrecise( - val: number, - inputFormat: string, - outputPrecision: number, - useShortSuffix: boolean, - includeSpace: string -) { - const ratio = ratioToSeconds[inputFormat] || 1; - const kind = ( - inputFormat in ratioToSeconds ? 'seconds' : inputFormat - ) as unitOfTime.DurationConstructor; - const valueInDuration = moment.duration(val * ratio, kind); - - return formatDuration( - val, - valueInDuration, - inputFormat, - outputPrecision, - useShortSuffix, - includeSpace - ); + const value = humanPrecise && val < 0 ? Math.abs(val * ratio) : val * ratio; + return moment.duration(value, kind); } export class DurationFormat extends FieldFormat { @@ -112,12 +90,12 @@ export class DurationFormat extends FieldFormat { }) + ' ' : ''; - const duration = parseInputAsDuration(val, inputFormat) as Record; + const duration = parseInputAsDuration(val, inputFormat, humanPrecise); const formatted = humanPrecise - ? formatInputHumanPrecise(val, inputFormat, outputPrecision, useShortSuffix, includeSpace) - : duration[outputFormat](); + ? formatDurationHumanPrecise(duration, outputPrecision, useShortSuffix, includeSpace, val < 0) + : (duration[outputFormat] as Function)(); - const precise = human || humanPrecise ? formatted : formatted.toFixed(outputPrecision); + const precise = human || humanPrecise ? formatted : Number(formatted).toFixed(outputPrecision); const type = DURATION_OUTPUT_FORMATS.find(({ method }) => method === outputFormat); const unitText = useShortSuffix ? type?.shortText : type?.text.toLowerCase(); @@ -128,53 +106,41 @@ export class DurationFormat extends FieldFormat { }; } -function formatDuration( - val: number, +// Array of units is to find the first unit duration value that is not 0 +const units = [ + { seconds: 31536000, method: 'asYears' }, + // Note: 30 days is used as a month in the duration format + { seconds: 2592000, method: 'asMonths' }, + { seconds: 604800, method: 'asWeeks' }, + { seconds: 86400, method: 'asDays' }, + { seconds: 3600, method: 'asHours' }, + { seconds: 60, method: 'asMinutes' }, + { seconds: 1, method: 'asSeconds' }, + { seconds: 0.001, method: 'asMilliseconds' }, +]; + +function formatDurationHumanPrecise( duration: moment.Duration, - inputFormat: string, outputPrecision: number, useShortSuffix: boolean, - includeSpace: string + includeSpace: string, + negativeValue: boolean ) { // return nothing when the duration is falsy or not correctly parsed (P0D) if (!duration || !duration.isValid()) return; - const units = [ - { unit: duration.years(), nextUnitRate: 12, method: 'asYears' }, - { unit: duration.months(), nextUnitRate: 4, method: 'asMonths' }, - { unit: duration.weeks(), nextUnitRate: 7, method: 'asWeeks' }, - { unit: duration.days(), nextUnitRate: 24, method: 'asDays' }, - { unit: duration.hours(), nextUnitRate: 60, method: 'asHours' }, - { unit: duration.minutes(), nextUnitRate: 60, method: 'asMinutes' }, - { unit: duration.seconds(), nextUnitRate: 1000, method: 'asSeconds' }, - { unit: duration.milliseconds(), nextUnitRate: 1000, method: 'asMilliseconds' }, - ]; + const valueInSeconds = duration.as('seconds'); const getUnitText = (method: string) => { const type = DURATION_OUTPUT_FORMATS.find(({ method: methodT }) => method === methodT); return useShortSuffix ? type?.shortText : type?.text.toLowerCase(); }; - for (let i = 0; i < units.length; i++) { - const unitValue = units[i].unit; - if (unitValue >= 1) { - const unitText = getUnitText(units[i].method); - - const value = Math.floor(unitValue); - if (units?.[i + 1]) { - const decimalPointValue = Math.floor(units[i + 1].unit); - return ( - (value + decimalPointValue / units[i].nextUnitRate).toFixed(outputPrecision) + - includeSpace + - unitText - ); - } else { - return unitValue.toFixed(outputPrecision) + includeSpace + unitText; - } + for (const unit of units) { + const unitValue = valueInSeconds / unit.seconds; + if (unitValue >= 1 || unit === units[units.length - 1]) { + // return a value if it's the first iteration where the value > 1, or the last iteration + const prefix = negativeValue ? '-' : ''; + return prefix + unitValue.toFixed(outputPrecision) + includeSpace + getUnitText(unit.method); } } - - const unitValue = units[units.length - 1].unit; - const unitText = getUnitText(units[units.length - 1].method); - - return unitValue.toFixed(outputPrecision) + includeSpace + unitText; } From e9c63bb5541470a57d3d537ba4ac1f5e1571c798 Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:53:41 +0200 Subject: [PATCH 038/104] Update dependency @elastic/charts to v64.1.0 (main) (#182087) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@elastic/charts](https://togithub.com/elastic/elastic-charts) | [`64.0.2` -> `64.1.0`](https://renovatebot.com/diffs/npm/@elastic%2fcharts/64.0.2/64.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@elastic%2fcharts/64.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@elastic%2fcharts/64.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@elastic%2fcharts/64.0.2/64.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@elastic%2fcharts/64.0.2/64.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
    elastic/elastic-charts (@​elastic/charts) ### [`v64.1.0`](https://togithub.com/elastic/elastic-charts/blob/HEAD/CHANGELOG.md#6410-2024-03-13) [Compare Source](https://togithub.com/elastic/elastic-charts/compare/v64.0.2...v64.1.0) ##### Features - **theme:** move annotation default styles to `Theme` ([#​2357](https://togithub.com/elastic/elastic-charts/issues/2357)) ([fe19ae2](https://togithub.com/elastic/elastic-charts/commit/fe19ae2cec3077ee34765d9be560935dd094a4ad)) #### [64.0.2](https://togithub.com/elastic/elastic-charts/compare/v64.0.1...v64.0.2) (2024-03-12) ##### Bug Fixes - **bullet:** full circle overlapping tick labels ([#​2350](https://togithub.com/elastic/elastic-charts/issues/2350)) ([edbff68](https://togithub.com/elastic/elastic-charts/commit/edbff681737ba319b455c81604e5ffff02b89f17)) - **deps:** update dependency [@​elastic/eui](https://togithub.com/elastic/eui) to ^93.3.0 ([#​2356](https://togithub.com/elastic/elastic-charts/issues/2356)) ([cf9ce81](https://togithub.com/elastic/elastic-charts/commit/cf9ce81c08b8d0ae93fce48504d2de3539d045d0)) - **deps:** update dependency [@​playwright/test](https://togithub.com/playwright/test) to ^1.42.1 ([#​2354](https://togithub.com/elastic/elastic-charts/issues/2354)) ([03581bc](https://togithub.com/elastic/elastic-charts/commit/03581bc44fae02309af9fbfa42c297f7414ec156)) #### [64.0.1](https://togithub.com/elastic/elastic-charts/compare/v64.0.0...v64.0.1) (2024-03-10) ##### Bug Fixes - **bullet:** add a11y summary and debugState ([#​2352](https://togithub.com/elastic/elastic-charts/issues/2352)) ([49a1b35](https://togithub.com/elastic/elastic-charts/commit/49a1b358b21fbda4e15a96ce984d460786396899)) - **deps:** update dependency [@​elastic/eui](https://togithub.com/elastic/eui) to ^93.2.0 ([#​2343](https://togithub.com/elastic/elastic-charts/issues/2343)) ([0701985](https://togithub.com/elastic/elastic-charts/commit/0701985a470ed98936439ccf4e21bb1d52df5e18))
    --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/elastic/kibana). --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- .../gauge_component.test.tsx.snap | 13 ++ .../partition_vis_component.test.tsx.snap | 78 +++++++++++ .../__snapshots__/xy_chart.test.tsx.snap | 130 ++++++++++++++++++ .../__snapshots__/donut_chart.test.tsx.snap | 13 ++ yarn.lock | 8 +- 6 files changed, 239 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ec2b1806feea2..de8acbf466e87 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@dnd-kit/utilities": "^2.0.0", "@elastic/apm-rum": "^5.16.0", "@elastic/apm-rum-react": "^2.0.2", - "@elastic/charts": "64.0.2", + "@elastic/charts": "64.1.0", "@elastic/datemath": "5.0.3", "@elastic/ecs": "^8.11.1", "@elastic/elasticsearch": "^8.13.0", diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap b/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap index 662bdc02805b0..0f9ddb6fb3490 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap @@ -407,6 +407,13 @@ exports[`GaugeComponent renders the chart 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -505,6 +512,12 @@ exports[`GaugeComponent renders the chart 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap index bad3e787de90e..3abe1b0971d0b 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap @@ -637,6 +637,13 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -735,6 +742,12 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -1554,6 +1567,13 @@ exports[`PartitionVisComponent should render correct structure for mosaic 1`] = "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -1652,6 +1672,12 @@ exports[`PartitionVisComponent should render correct structure for mosaic 1`] = "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -2531,6 +2557,13 @@ exports[`PartitionVisComponent should render correct structure for multi-metric "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -2629,6 +2662,12 @@ exports[`PartitionVisComponent should render correct structure for multi-metric "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -3510,6 +3549,13 @@ exports[`PartitionVisComponent should render correct structure for pie 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -3608,6 +3654,12 @@ exports[`PartitionVisComponent should render correct structure for pie 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -4427,6 +4479,13 @@ exports[`PartitionVisComponent should render correct structure for treemap 1`] = "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -4525,6 +4584,12 @@ exports[`PartitionVisComponent should render correct structure for treemap 1`] = "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -5299,6 +5364,13 @@ exports[`PartitionVisComponent should render correct structure for waffle 1`] = "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -5397,6 +5469,12 @@ exports[`PartitionVisComponent should render correct structure for waffle 1`] = "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, diff --git a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap index 73c03e9c1c2f0..70dabc254ed51 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap @@ -979,6 +979,13 @@ exports[`XYChart component it renders area 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -1077,6 +1084,12 @@ exports[`XYChart component it renders area 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -2515,6 +2528,13 @@ exports[`XYChart component it renders bar 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -2613,6 +2633,12 @@ exports[`XYChart component it renders bar 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -4051,6 +4077,13 @@ exports[`XYChart component it renders horizontal bar 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -4149,6 +4182,12 @@ exports[`XYChart component it renders horizontal bar 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -5587,6 +5626,13 @@ exports[`XYChart component it renders line 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -5685,6 +5731,12 @@ exports[`XYChart component it renders line 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -7123,6 +7175,13 @@ exports[`XYChart component it renders stacked area 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -7221,6 +7280,12 @@ exports[`XYChart component it renders stacked area 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -8659,6 +8724,13 @@ exports[`XYChart component it renders stacked bar 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -8757,6 +8829,12 @@ exports[`XYChart component it renders stacked bar 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -10195,6 +10273,13 @@ exports[`XYChart component it renders stacked horizontal bar 1`] = ` "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -10293,6 +10378,12 @@ exports[`XYChart component it renders stacked horizontal bar 1`] = ` "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -11761,6 +11852,13 @@ exports[`XYChart component split chart should render split chart if both, splitR "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -11859,6 +11957,12 @@ exports[`XYChart component split chart should render split chart if both, splitR "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -13535,6 +13639,13 @@ exports[`XYChart component split chart should render split chart if splitColumnA "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -13633,6 +13744,12 @@ exports[`XYChart component split chart should render split chart if splitColumnA "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, @@ -15302,6 +15419,13 @@ exports[`XYChart component split chart should render split chart if splitRowAcce "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -15400,6 +15524,12 @@ exports[`XYChart component split chart should render split chart if splitRowAcce "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap index 363aee4953ab5..452d12596bda1 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap @@ -420,6 +420,13 @@ exports[`DonutChart component passes correct props without errors for valid prop "spacingBuffer": 10, "verticalWidth": 200, }, + "lineAnnotation": Object { + "line": Object { + "opacity": 1, + "stroke": "#69707D", + "strokeWidth": 1, + }, + }, "lineSeriesStyle": Object { "fit": Object { "line": Object { @@ -518,6 +525,12 @@ exports[`DonutChart component passes correct props without errors for valid prop "sectorLineStroke": "#FFF", "sectorLineWidth": 1.5, }, + "rectAnnotation": Object { + "fill": "#69707D", + "opacity": 0.25, + "stroke": "#69707D", + "strokeWidth": 0, + }, "scales": Object { "barsPadding": 0.25, "histogramPadding": 0.05, diff --git a/yarn.lock b/yarn.lock index 746867f15231c..b3f1041b2b5cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1665,10 +1665,10 @@ dependencies: object-hash "^1.3.0" -"@elastic/charts@64.0.2": - version "64.0.2" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-64.0.2.tgz#3df497aad0dd2e8df7221a08e21d0b72daee5d36" - integrity sha512-cSW44eorH+Ih0YOliLdLamYi30RXQppAIuc4/NzG9JkUFufkAIN5qOgY5qW3gU0WfsbY+GIVUZSB4xh/Zsw1Ug== +"@elastic/charts@64.1.0": + version "64.1.0" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-64.1.0.tgz#aa52332cec68ea52be25e387774267027311b8ca" + integrity sha512-jZ9fnujjzHd24m0Fv5zURbxrb/MzIRUwlvyocjAn/y2yLHhlqMK6XWHfMoqIAgZ0iVVojfEPXnnc34PPT4KDIA== dependencies: "@popperjs/core" "^2.11.8" bezier-easing "^2.1.0" From 74fdd1b5f25c783ef95b3fddb2eaef03ff597345 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 30 Apr 2024 15:09:08 +0200 Subject: [PATCH 039/104] [Discover][Obs ai assistant] Set the index pattern on the context api to generate correct ES|QL queries etc (#182090) ## Summary Reverting the revert of https://github.com/elastic/kibana/pull/181001#issuecomment-2084827044 the only change is the removal of the ml plugin dependency from the obs-ai-assistant --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/discover/kibana.jsonc | 3 ++- .../main/components/layout/discover_layout.tsx | 11 +++++++++++ src/plugins/discover/public/build_services.ts | 3 +++ src/plugins/discover/public/plugin.tsx | 6 ++++++ src/plugins/discover/tsconfig.json | 3 ++- .../observability_ai_assistant/public/types.ts | 3 --- .../observability_ai_assistant/tsconfig.json | 1 - 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/plugins/discover/kibana.jsonc b/src/plugins/discover/kibana.jsonc index 17693545dd6d0..9b892ee79fe16 100644 --- a/src/plugins/discover/kibana.jsonc +++ b/src/plugins/discover/kibana.jsonc @@ -37,7 +37,8 @@ "savedObjectsTaggingOss", "lens", "noDataPage", - "globalSearch" + "globalSearch", + "observabilityAIAssistant" ], "requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedSearch", "savedObjects"], "extraPublicDirs": ["common"] diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index 344e0b36c9d0e..a104dc3c9d73b 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -71,6 +71,7 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { filterManager, history, spaces, + observabilityAIAssistant, } = useDiscoverServices(); const pageBackgroundColor = useEuiBackgroundColor('plain'); const globalQueryState = data.query.getState(); @@ -132,6 +133,16 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { sort, }); + // The assistant is getting the state from the url correctly + // expect from the index pattern where we have only the dataview id + useEffect(() => { + return observabilityAIAssistant?.service.setScreenContext({ + screenDescription: `The user is looking at the Discover view on the ${ + isPlainRecord ? 'ES|QL' : 'dataView' + } mode. The index pattern is the ${dataView.getIndexPattern()}`, + }); + }, [dataView, isPlainRecord, observabilityAIAssistant?.service]); + const onAddFilter = useCallback( (field: DataViewField | string, values: unknown, operation: '+' | '-') => { const fieldName = typeof field === 'string' ? field : field.name; diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index fc599bd59620e..7f7bcdee2154b 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -54,6 +54,7 @@ import type { LensPublicStart } from '@kbn/lens-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { ContentClient } from '@kbn/content-management-plugin/public'; +import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public'; import { memoize, noop } from 'lodash'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; import { DiscoverStartPlugins } from './plugin'; @@ -123,6 +124,7 @@ export interface DiscoverServices { uiActions: UiActionsStart; contentClient: ContentClient; noDataPage?: NoDataPagePluginStart; + observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export const buildServices = memoize( @@ -203,6 +205,7 @@ export const buildServices = memoize( uiActions: plugins.uiActions, contentClient: plugins.contentManagement.client, noDataPage: plugins.noDataPage, + observabilityAIAssistant: plugins.observabilityAIAssistant, }; } ); diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 46cbf95d299b1..902cc0a38e717 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -46,6 +46,10 @@ import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; import { TRUNCATE_MAX_HEIGHT, ENABLE_ESQL } from '@kbn/discover-utils'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; +import type { + ObservabilityAIAssistantPublicSetup, + ObservabilityAIAssistantPublicStart, +} from '@kbn/observability-ai-assistant-plugin/public'; import { PLUGIN_ID } from '../common'; import { registerFeature } from './register_feature'; import { buildServices, UrlTracker } from './build_services'; @@ -166,6 +170,7 @@ export interface DiscoverSetupPlugins { data: DataPublicPluginSetup; expressions: ExpressionsSetup; globalSearch?: GlobalSearchPluginSetup; + observabilityAIAssistant?: ObservabilityAIAssistantPublicSetup; } /** @@ -196,6 +201,7 @@ export interface DiscoverStartPlugins { lens: LensPublicStart; contentManagement: ContentManagementPublicStart; noDataPage?: NoDataPagePluginStart; + observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; } export type StartRenderServices = Pick; diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index b10dee36e3fb7..6b576f3a08c1a 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -83,7 +83,8 @@ "@kbn/deeplinks-analytics", "@kbn/shared-ux-markdown", "@kbn/data-view-utils", - "@kbn/presentation-publishing" + "@kbn/presentation-publishing", + "@kbn/observability-ai-assistant-plugin" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts index 0567324e164dc..69a1a6821197b 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts @@ -6,7 +6,6 @@ */ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; -import type { MlPluginSetup, MlPluginStart } from '@kbn/ml-plugin/public'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; import type { Observable } from 'rxjs'; @@ -104,13 +103,11 @@ export interface ConfigSchema {} export interface ObservabilityAIAssistantPluginSetupDependencies { licensing: {}; security: SecurityPluginSetup; - ml: MlPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { licensing: LicensingPluginStart; security: SecurityPluginStart; - ml: MlPluginStart; triggersActionsUi: TriggersAndActionsUIPublicPluginStart; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json index cc66498fa5d4e..b3fe0f8c8f6fc 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json @@ -41,7 +41,6 @@ "@kbn/babel-register", "@kbn/dev-cli-runner", "@kbn/core-analytics-browser", - "@kbn/ml-plugin", "@kbn/expect", "@kbn/apm-synthtrace-client", "@kbn/apm-synthtrace", From 5814f2e0cea6a2ad797c10105badbbc313635bdd Mon Sep 17 00:00:00 2001 From: Kathleen DeRusso Date: Tue, 30 Apr 2024 09:17:01 -0400 Subject: [PATCH 040/104] [Dev console] Fix some issues with AutoComplete (#182002) Resolves https://github.com/elastic/kibana/issues/181618 by adding delete by query AutoComplete for the query. Here's what it looks like now: https://github.com/elastic/kibana/assets/63422879/ff2c0c18-4f1e-41f3-b18d-b9a4a5377dd1 Also fixes a syntax issue with rule query AutoComplete where we added an extra `query` that would result in a syntax error. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../console/server/lib/spec_definitions/js/query/dsl.ts | 4 +--- .../spec_definitions/json/overrides/delete_by_query.json | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/plugins/console/server/lib/spec_definitions/json/overrides/delete_by_query.json diff --git a/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts index c83f8ebe713c0..273c5eab9c889 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts @@ -519,9 +519,7 @@ export const query = (specService: SpecDefinitionsService) => { }, rule_query: { __template: { - organic: { - query: {}, - }, + organic: {}, ruleset_id: '', match_criteria: { FIELD: 'VALUE', diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/delete_by_query.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/delete_by_query.json new file mode 100644 index 0000000000000..a6cdc2dbf0e77 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/json/overrides/delete_by_query.json @@ -0,0 +1,9 @@ +{ + "delete_by_query": { + "data_autocomplete_rules": { + "query": { + "__scope_link": "GLOBAL.query" + } + } + } +} From a1ada760269cf895e43fbc6c5775a219159e651f Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:27:32 +0900 Subject: [PATCH 041/104] [RAM][HTTP Versioning] Version GET Rule Route (#181304) ## Summary Parent Issue: https://github.com/elastic/kibana/issues/157883 Issue: https://github.com/elastic/kibana/issues/181263 Versions the GET rule endpoint with added input and output validation. ``` GET /internal/alerting/rule/{id} GET /api/alerting/rule/{id} ``` ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../common/routes/rule/apis/get/index.ts | 15 ++ .../routes/rule/apis/get/schemas/latest.ts | 8 + .../common/routes/rule/apis/get/schemas/v1.ts | 12 ++ .../routes/rule/apis/get/types/latest.ts | 8 + .../common/routes/rule/apis/get/types/v1.ts | 16 ++ .../common/routes/rule/response/types/v1.ts | 2 +- .../schedule/schedule_backfill.test.ts | 2 + .../rule/methods/get/get_rule.test.ts} | 103 +++++++--- .../application/rule/methods/get/get_rule.ts | 113 +++++++++++ .../application/rule/methods/get/index.ts | 9 + .../get/schemas/get_rule_params_schema.ts | 15 ++ .../rule/methods/get/schemas/index.ts | 8 + .../rule/methods/get/types/get_rule_params.ts | 11 ++ .../rule/methods/get/types/index.ts | 8 + .../application/rule/schemas/rule_schemas.ts | 2 + ...ransform_rule_attributes_to_rule_domain.ts | 9 +- .../transform_rule_domain_to_rule.test.ts | 177 ++++++++++++++++++ .../transform_rule_domain_to_rule.ts | 8 +- ...ransform_rule_domain_to_rule_attributes.ts | 28 +-- .../server/application/rule/types/rule.ts | 6 +- .../server/data/rule/types/rule_attributes.ts | 2 +- .../alerting/server/routes/get_rule.ts | 129 ------------- .../plugins/alerting/server/routes/index.ts | 2 +- .../apis/get/get_rule_route.test.ts} | 24 +-- .../routes/rule/apis/get/get_rule_route.ts | 87 +++++++++ .../apis/resolve/resolve_rule_route.test.ts | 4 +- .../transform_rule_to_rule_response/v1.ts | 22 ++- .../server/rules_client/methods/get.ts | 79 -------- .../methods/get_action_error_log.ts | 4 +- .../rules_client/methods/get_alert_state.ts | 4 +- .../rules_client/methods/get_alert_summary.ts | 4 +- .../rules_client/methods/get_execution_kpi.ts | 4 +- .../rules_client/methods/get_execution_log.ts | 4 +- .../server/rules_client/rules_client.ts | 6 +- .../tests/get_alert_state.test.ts | 39 +++- .../functional/es_archives/alerts/data.json | 24 +++ .../es_archives/alerts/mappings.json | 3 + .../rules_scheduled_task_id/rules/data.json | 2 + .../rules/mappings.json | 3 + 39 files changed, 707 insertions(+), 299 deletions(-) create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/get/index.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/get/types/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/get/types/v1.ts rename x-pack/plugins/alerting/server/{rules_client/tests/get.test.ts => application/rule/methods/get/get_rule.test.ts} (87%) create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/schemas/get_rule_params_schema.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/schemas/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/types/get_rule_params.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/get/types/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.test.ts delete mode 100644 x-pack/plugins/alerting/server/routes/get_rule.ts rename x-pack/plugins/alerting/server/routes/{get_rule.test.ts => rule/apis/get/get_rule_route.test.ts} (90%) create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts delete mode 100644 x-pack/plugins/alerting/server/rules_client/methods/get.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/get/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/get/index.ts new file mode 100644 index 0000000000000..2422664dbba56 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/get/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getRuleRequestParamsSchema } from './schemas/latest'; +export type { GetRuleRequestParams, GetRuleResponse } from './types/latest'; + +export { getRuleRequestParamsSchema as getRuleRequestParamsSchemaV1 } from './schemas/v1'; +export type { + GetRuleRequestParams as GetRuleRequestParamsV1, + GetRuleResponse as GetRuleResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/v1.ts new file mode 100644 index 0000000000000..18ac4263043e9 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/get/schemas/v1.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 { schema } from '@kbn/config-schema'; + +export const getRuleRequestParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/get/types/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/get/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/get/types/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/get/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/get/types/v1.ts new file mode 100644 index 0000000000000..84370ebd28240 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/get/types/v1.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { RuleParamsV1, RuleResponseV1 } from '../../../response'; +import { getRuleRequestParamsSchemaV1 } from '..'; + +export type GetRuleRequestParams = TypeOf; + +export interface GetRuleResponse { + body: RuleResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts index 25e08ab407ebb..e11daa418022a 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts @@ -43,7 +43,7 @@ export interface RuleResponse { mute_all: RuleResponseSchemaType['mute_all']; notify_when?: RuleResponseSchemaType['notify_when']; muted_alert_ids: RuleResponseSchemaType['muted_alert_ids']; - execution_status: RuleResponseSchemaType['execution_status']; + execution_status?: RuleResponseSchemaType['execution_status']; monitoring?: RuleResponseSchemaType['monitoring']; snooze_schedule?: RuleResponseSchemaType['snooze_schedule']; active_snoozes?: RuleResponseSchemaType['active_snoozes']; diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts index c4944ba66daff..4767a344f5153 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts @@ -400,6 +400,7 @@ describe('scheduleBackfill()', () => { rules: [ { id: existingDecryptedRule1.id, + legacyId: null, actions: existingDecryptedRule1.attributes.actions, alertTypeId: existingDecryptedRule1.attributes.alertTypeId, apiKey: existingDecryptedRule1.attributes.apiKey, @@ -430,6 +431,7 @@ describe('scheduleBackfill()', () => { }, { id: existingDecryptedRule2.id, + legacyId: null, actions: existingDecryptedRule2.attributes.actions, alertTypeId: existingDecryptedRule2.attributes.alertTypeId, apiKey: existingDecryptedRule2.attributes.apiKey, diff --git a/x-pack/plugins/alerting/server/rules_client/tests/get.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.test.ts similarity index 87% rename from x-pack/plugins/alerting/server/rules_client/tests/get.test.ts rename to x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.test.ts index ac3a8d78a7595..c0f0caeed673f 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/get.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.test.ts @@ -6,7 +6,7 @@ */ import { AlertConsumers } from '@kbn/rule-data-utils'; -import { RulesClient, ConstructorOptions } from '../rules_client'; +import { RulesClient, ConstructorOptions } from '../../../../rules_client/rules_client'; import { savedObjectsClientMock, loggingSystemMock, @@ -14,21 +14,21 @@ import { uiSettingsServiceMock, } from '@kbn/core/server/mocks'; import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; -import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; -import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; +import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock'; +import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; -import { AlertingAuthorization } from '../../authorization/alerting_authorization'; +import { AlertingAuthorization } from '../../../../authorization/alerting_authorization'; import { ActionsAuthorization } from '@kbn/actions-plugin/server'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { getBeforeSetup, setGlobalDate } from './lib'; -import { RecoveredActionGroup } from '../../../common'; -import { formatLegacyActions } from '../lib'; -import { ConnectorAdapterRegistry } from '../../connector_adapters/connector_adapter_registry'; -import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; -import { backfillClientMock } from '../../backfill_client/backfill_client.mock'; +import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib'; +import { RecoveredActionGroup } from '../../../../../common'; +import { formatLegacyActions } from '../../../../rules_client/lib'; +import { ConnectorAdapterRegistry } from '../../../../connector_adapters/connector_adapter_registry'; +import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; +import { backfillClientMock } from '../../../../backfill_client/backfill_client.mock'; -jest.mock('../lib/siem_legacy_actions/format_legacy_actions', () => { +jest.mock('../../../../rules_client/lib/siem_legacy_actions/format_legacy_actions', () => { return { formatLegacyActions: jest.fn(), }; @@ -91,6 +91,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ @@ -128,6 +132,10 @@ describe('get()', () => { ], "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2020-08-20T19:23:38.000Z, + "status": "unknown", + }, "id": "1", "notifyWhen": "onActiveAlert", "params": Object { @@ -143,11 +151,12 @@ describe('get()', () => { `); expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1); expect(unsecuredSavedObjectsClient.get.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); + Array [ + "alert", + "1", + undefined, + ] + `); }); test('gets rule with actions using preconfigured connectors', async () => { @@ -161,6 +170,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ @@ -214,6 +227,10 @@ describe('get()', () => { ], "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2020-08-20T19:23:38.000Z, + "status": "unknown", + }, "id": "1", "notifyWhen": "onActiveAlert", "params": Object { @@ -229,11 +246,12 @@ describe('get()', () => { `); expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1); expect(unsecuredSavedObjectsClient.get.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); + Array [ + "alert", + "1", + undefined, + ] + `); }); test('gets rule with actions using system connectors', async () => { @@ -247,6 +265,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ @@ -289,6 +311,10 @@ describe('get()', () => { ], "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2020-08-20T19:23:38.000Z, + "status": "unknown", + }, "id": "1", "notifyWhen": "onActiveAlert", "params": Object { @@ -311,11 +337,12 @@ describe('get()', () => { `); expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1); expect(unsecuredSavedObjectsClient.get.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); + Array [ + "alert", + "1", + undefined, + ] + `); }); test('should call useSavedObjectReferences.injectReferences if defined for rule type', async () => { @@ -356,6 +383,10 @@ describe('get()', () => { bar: true, parameterThatIsSavedObjectRef: 'soRef_0', }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ @@ -406,6 +437,10 @@ describe('get()', () => { ], "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2020-08-20T19:23:38.000Z, + "status": "unknown", + }, "id": "1", "notifyWhen": "onActiveAlert", "params": Object { @@ -487,6 +522,10 @@ describe('get()', () => { bar: true, parameterThatIsSavedObjectRef: 'soRef_0', }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ @@ -530,6 +569,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [ { group: 'default', @@ -592,6 +635,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [], }, references: [], @@ -648,6 +695,10 @@ describe('get()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), actions: [ diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.ts new file mode 100644 index 0000000000000..9577673cc97b7 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/get_rule.ts @@ -0,0 +1,113 @@ +/* + * 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 Boom from '@hapi/boom'; +import { AlertConsumers } from '@kbn/rule-data-utils'; +import { + SanitizedRule, + SanitizedRuleWithLegacyId, + Rule as DeprecatedRule, +} from '../../../../types'; +import { ReadOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { formatLegacyActions } from '../../../../rules_client/lib'; +import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; +import { GetRuleParams } from './types'; +import { getRuleParamsSchema } from './schemas'; +import { getRuleSo } from '../../../../data/rule'; +import { transformRuleAttributesToRuleDomain, transformRuleDomainToRule } from '../../transforms'; +import { RuleParams } from '../../types'; +import { ruleDomainSchema } from '../../schemas'; + +export async function getRule( + context: RulesClientContext, + params: GetRuleParams +): Promise | SanitizedRuleWithLegacyId> { + const { + id, + includeLegacyId = false, + includeSnoozeData = false, + excludeFromPublicApi = false, + } = params; + + try { + getRuleParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating get data - ${error.message}`); + } + + const result = await getRuleSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + id, + }); + + try { + await context.authorization.ensureAuthorized({ + ruleTypeId: result.attributes.alertTypeId, + consumer: result.attributes.consumer, + operation: ReadOperations.Get, + entity: AlertingAuthorizationEntity.Rule, + }); + } catch (error) { + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.GET, + savedObject: { type: RULE_SAVED_OBJECT_TYPE, id }, + error, + }) + ); + throw error; + } + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.GET, + savedObject: { type: RULE_SAVED_OBJECT_TYPE, id }, + }) + ); + + const ruleType = context.ruleTypeRegistry.get(result.attributes.alertTypeId); + + const ruleDomain = transformRuleAttributesToRuleDomain( + result.attributes, + { + id: result.id, + logger: context.logger, + ruleType, + references: result.references, + includeSnoozeData, + }, + context.isSystemAction + ); + + // Try to validate created rule, but don't throw. + try { + ruleDomainSchema.validate(ruleDomain); + } catch (e) { + context.logger.warn(`Error validating get rule domain object for id: ${id}, ${e}`); + } + + // Convert domain rule to rule (Remove certain properties) + const rule = transformRuleDomainToRule(ruleDomain, { + isPublic: excludeFromPublicApi, + includeLegacyId, + }); + + // format legacy actions for SIEM rules + if (result.attributes.consumer === AlertConsumers.SIEM) { + const [migratedRule] = await formatLegacyActions([rule as DeprecatedRule], { + savedObjectsClient: context.unsecuredSavedObjectsClient, + logger: context.logger, + }); + + return migratedRule; + } + + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + return rule as SanitizedRule; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/index.ts new file mode 100644 index 0000000000000..cd47bf0db31ab --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/index.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { GetRuleParams } from './types'; +export { getRule } from './get_rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/get_rule_params_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/get_rule_params_schema.ts new file mode 100644 index 0000000000000..5c5c82e04d2a2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/get_rule_params_schema.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const getRuleParamsSchema = schema.object({ + id: schema.string(), + includeLegacyId: schema.maybe(schema.boolean()), + includeSnoozeData: schema.maybe(schema.boolean()), + excludeFromPublicApi: schema.maybe(schema.boolean()), +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/index.ts new file mode 100644 index 0000000000000..fed991d8a07b1 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './get_rule_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/types/get_rule_params.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/types/get_rule_params.ts new file mode 100644 index 0000000000000..63f6724829f28 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/types/get_rule_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { getRuleParamsSchema } from '../schemas'; + +export type GetRuleParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/get/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/get/types/index.ts new file mode 100644 index 0000000000000..553499a994ff6 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/get/types/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './get_rule_params'; diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts index 23856d74dec83..cd3b465244976 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts @@ -174,6 +174,7 @@ export const ruleDomainSchema = schema.object({ running: schema.maybe(schema.nullable(schema.boolean())), viewInAppRelativeUrl: schema.maybe(schema.nullable(schema.string())), alertDelay: schema.maybe(alertDelaySchema), + legacyId: schema.maybe(schema.nullable(schema.string())), }); /** @@ -213,4 +214,5 @@ export const ruleSchema = schema.object({ running: schema.maybe(schema.nullable(schema.boolean())), viewInAppRelativeUrl: schema.maybe(schema.nullable(schema.string())), alertDelay: schema.maybe(alertDelaySchema), + legacyId: schema.maybe(schema.nullable(schema.string())), }); diff --git a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index 41e251ff47c3e..ffcc664b0e76e 100644 --- a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -10,7 +10,7 @@ import { SavedObjectReference } from '@kbn/core/server'; import { ruleExecutionStatusValues } from '../constants'; import { getRuleSnoozeEndTime } from '../../../lib'; import { RuleDomain, Monitoring, RuleParams } from '../types'; -import { RuleAttributes } from '../../../data/rule/types'; +import { RuleAttributes, RuleExecutionStatusAttributes } from '../../../data/rule/types'; import { PartialRule } from '../../../types'; import { UntypedNormalizedRuleType } from '../../../rule_type_registry'; import { injectReferencesIntoParams } from '../../../rules_client/common'; @@ -32,7 +32,7 @@ const INITIAL_LAST_RUN_METRICS = { const transformEsExecutionStatus = ( logger: Logger, ruleId: string, - esRuleExecutionStatus: RuleAttributes['executionStatus'] + esRuleExecutionStatus: RuleExecutionStatusAttributes ): RuleDomain['executionStatus'] => { const { lastExecutionDate, @@ -204,7 +204,9 @@ export const transformRuleAttributesToRuleDomain = { + const MOCK_API_KEY = Buffer.from('123:abc').toString('base64'); + const defaultAction = { + uuid: '1', + group: 'default', + id: '1', + actionTypeId: '.test', + params: {}, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval' as const, + throttle: '1m', + }, + alertsFilter: { + query: { + kql: 'test:1', + dsl: '{}', + filters: [], + }, + }, + }; + + const systemAction = { + id: '2', + uuid: '123', + actionTypeId: '.test-system-action', + params: {}, + }; + + const rule: RuleDomain<{}> = { + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + legacyId: 'legacyId', + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKey: MOCK_API_KEY, + apiKeyOwner: 'user', + }; + + it('should transform rule domain to rule', () => { + const result = transformRuleDomainToRule(rule); + + expect(result).toEqual({ + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKeyOwner: 'user', + }); + }); + + it('should remove public fields if isPublic is true', () => { + const result = transformRuleDomainToRule(rule, { + isPublic: true, + }); + + expect(result).toEqual({ + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + muteAll: false, + mutedInstanceIds: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKeyOwner: 'user', + }); + }); + + it('should include legacy id if includeLegacyId is true', () => { + const result = transformRuleDomainToRule(rule, { + includeLegacyId: true, + }); + + expect(result).toEqual({ + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + legacyId: 'legacyId', + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKeyOwner: 'user', + }); + }); +}); diff --git a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts index f4f42a0846bc3..76e90475132b4 100644 --- a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts @@ -9,13 +9,14 @@ import { RuleDomain, Rule, RuleParams } from '../types'; interface TransformRuleDomainToRuleOptions { isPublic?: boolean; + includeLegacyId?: boolean; } export const transformRuleDomainToRule = ( ruleDomain: RuleDomain, options?: TransformRuleDomainToRuleOptions ): Rule => { - const { isPublic = false } = options || {}; + const { isPublic = false, includeLegacyId = false } = options || {}; const rule: Rule = { id: ruleDomain.id, @@ -51,6 +52,7 @@ export const transformRuleDomainToRule = ( running: ruleDomain.running, viewInAppRelativeUrl: ruleDomain.viewInAppRelativeUrl, alertDelay: ruleDomain.alertDelay, + legacyId: ruleDomain.legacyId, }; if (isPublic) { @@ -61,6 +63,10 @@ export const transformRuleDomainToRule = ( delete rule.viewInAppRelativeUrl; } + if (!includeLegacyId) { + delete rule.legacyId; + } + // Remove all undefined keys to clean up the object type RuleKeys = keyof Rule; for (const key in rule) { diff --git a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts index 0e70525981496..dfa4ba7acb3cb 100644 --- a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts +++ b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts @@ -53,17 +53,23 @@ export const transformRuleDomainToRuleAttributes = ({ muteAll: rule.muteAll, mutedInstanceIds: rule.mutedInstanceIds, ...(meta ? { meta } : {}), - executionStatus: { - status: rule.executionStatus.status, - lastExecutionDate: rule.executionStatus.lastExecutionDate.toISOString(), - ...(rule.executionStatus.lastDuration - ? { lastDuration: rule.executionStatus.lastDuration } - : {}), - ...(rule.executionStatus.error !== undefined ? { error: rule.executionStatus.error } : {}), - ...(rule.executionStatus.warning !== undefined - ? { warning: rule.executionStatus.warning } - : {}), - }, + ...(rule.executionStatus + ? { + executionStatus: { + status: rule.executionStatus.status, + lastExecutionDate: rule.executionStatus.lastExecutionDate.toISOString(), + ...(rule.executionStatus.lastDuration + ? { lastDuration: rule.executionStatus.lastDuration } + : {}), + ...(rule.executionStatus.error !== undefined + ? { error: rule.executionStatus.error } + : {}), + ...(rule.executionStatus.warning !== undefined + ? { warning: rule.executionStatus.warning } + : {}), + }, + } + : {}), ...(rule.monitoring ? { monitoring: rule.monitoring } : {}), ...(rule.snoozeSchedule ? { snoozeSchedule: rule.snoozeSchedule } : {}), ...(rule.isSnoozedUntil !== undefined diff --git a/x-pack/plugins/alerting/server/application/rule/types/rule.ts b/x-pack/plugins/alerting/server/application/rule/types/rule.ts index da86154d6b8e5..ee5a5208ffe55 100644 --- a/x-pack/plugins/alerting/server/application/rule/types/rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/types/rule.ts @@ -72,7 +72,7 @@ export interface Rule { muteAll: RuleSchemaType['muteAll']; notifyWhen?: RuleSchemaType['notifyWhen']; mutedInstanceIds: RuleSchemaType['mutedInstanceIds']; - executionStatus: RuleExecutionStatus; + executionStatus?: RuleExecutionStatus; monitoring?: RuleSchemaType['monitoring']; snoozeSchedule?: RuleSchemaType['snoozeSchedule']; activeSnoozes?: RuleSchemaType['activeSnoozes']; @@ -83,6 +83,7 @@ export interface Rule { running?: RuleSchemaType['running']; viewInAppRelativeUrl?: RuleSchemaType['viewInAppRelativeUrl']; alertDelay?: RuleSchemaType['alertDelay']; + legacyId?: RuleSchemaType['legacyId']; } export interface RuleDomain { @@ -109,7 +110,7 @@ export interface RuleDomain { muteAll: RuleDomainSchemaType['muteAll']; notifyWhen?: RuleDomainSchemaType['notifyWhen']; mutedInstanceIds: RuleDomainSchemaType['mutedInstanceIds']; - executionStatus: RuleExecutionStatus; + executionStatus?: RuleExecutionStatus; monitoring?: RuleDomainSchemaType['monitoring']; snoozeSchedule?: RuleDomainSchemaType['snoozeSchedule']; activeSnoozes?: RuleDomainSchemaType['activeSnoozes']; @@ -120,4 +121,5 @@ export interface RuleDomain { running?: RuleDomainSchemaType['running']; viewInAppRelativeUrl?: RuleDomainSchemaType['viewInAppRelativeUrl']; alertDelay?: RuleSchemaType['alertDelay']; + legacyId?: RuleSchemaType['legacyId']; } diff --git a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts index 151c71b7d79f4..35361012ca404 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts @@ -171,7 +171,7 @@ export interface RuleAttributes { muteAll: boolean; mutedInstanceIds: string[]; meta?: RuleMetaAttributes; - executionStatus: RuleExecutionStatusAttributes; + executionStatus?: RuleExecutionStatusAttributes; monitoring?: RuleMonitoringAttributes; snoozeSchedule?: RuleSnoozeScheduleAttributes[]; isSnoozedUntil?: string | null; diff --git a/x-pack/plugins/alerting/server/routes/get_rule.ts b/x-pack/plugins/alerting/server/routes/get_rule.ts deleted file mode 100644 index f739f946975e6..0000000000000 --- a/x-pack/plugins/alerting/server/routes/get_rule.ts +++ /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 { omit } from 'lodash'; -import { schema } from '@kbn/config-schema'; -import { IRouter } from '@kbn/core/server'; -import { ILicenseState } from '../lib'; -import { verifyAccessAndContext, rewriteRuleLastRun } from './lib'; -import { - RuleTypeParams, - AlertingRequestHandlerContext, - BASE_ALERTING_API_PATH, - INTERNAL_BASE_ALERTING_API_PATH, - SanitizedRule, -} from '../types'; -import { transformRuleActions } from './rule/transforms'; - -const paramSchema = schema.object({ - id: schema.string(), -}); - -const rewriteBodyRes = ({ - alertTypeId, - createdBy, - updatedBy, - createdAt, - updatedAt, - apiKeyOwner, - apiKeyCreatedByUser, - notifyWhen, - muteAll, - mutedInstanceIds, - executionStatus, - actions, - systemActions, - scheduledTaskId, - snoozeSchedule, - isSnoozedUntil, - lastRun, - nextRun, - viewInAppRelativeUrl, - ...rest -}: SanitizedRule) => ({ - ...rest, - rule_type_id: alertTypeId, - created_by: createdBy, - updated_by: updatedBy, - created_at: createdAt, - updated_at: updatedAt, - api_key_owner: apiKeyOwner, - notify_when: notifyWhen, - muted_alert_ids: mutedInstanceIds, - mute_all: muteAll, - ...(isSnoozedUntil !== undefined ? { is_snoozed_until: isSnoozedUntil } : {}), - snooze_schedule: snoozeSchedule, - scheduled_task_id: scheduledTaskId, - execution_status: executionStatus && { - ...omit(executionStatus, 'lastExecutionDate', 'lastDuration'), - last_execution_date: executionStatus.lastExecutionDate, - last_duration: executionStatus.lastDuration, - }, - actions: transformRuleActions(actions, systemActions), - ...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}), - ...(nextRun ? { next_run: nextRun } : {}), - ...(viewInAppRelativeUrl ? { view_in_app_relative_url: viewInAppRelativeUrl } : {}), - ...(apiKeyCreatedByUser !== undefined ? { api_key_created_by_user: apiKeyCreatedByUser } : {}), -}); - -interface BuildGetRulesRouteParams { - licenseState: ILicenseState; - path: string; - router: IRouter; - excludeFromPublicApi?: boolean; -} -const buildGetRuleRoute = ({ - licenseState, - path, - router, - excludeFromPublicApi = false, -}: BuildGetRulesRouteParams) => { - router.get( - { - path, - validate: { - params: paramSchema, - }, - }, - router.handleLegacyErrors( - verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); - const { id } = req.params; - const rule = await rulesClient.get({ - id, - excludeFromPublicApi, - includeSnoozeData: true, - }); - return res.ok({ - body: rewriteBodyRes(rule), - }); - }) - ) - ); -}; - -export const getRuleRoute = ( - router: IRouter, - licenseState: ILicenseState -) => - buildGetRuleRoute({ - excludeFromPublicApi: true, - licenseState, - path: `${BASE_ALERTING_API_PATH}/rule/{id}`, - router, - }); - -export const getInternalRuleRoute = ( - router: IRouter, - licenseState: ILicenseState -) => - buildGetRuleRoute({ - excludeFromPublicApi: false, - licenseState, - path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}`, - router, - }); diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 4261b8f9c9776..2f0f773a995d3 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -14,7 +14,7 @@ import { GetAlertIndicesAlias, ILicenseState } from '../lib'; import { defineLegacyRoutes } from './legacy'; import { AlertingRequestHandlerContext } from '../types'; import { createRuleRoute } from './rule/apis/create'; -import { getRuleRoute, getInternalRuleRoute } from './get_rule'; +import { getRuleRoute, getInternalRuleRoute } from './rule/apis/get/get_rule_route'; import { updateRuleRoute } from './rule/apis/update/update_rule_route'; import { deleteRuleRoute } from './delete_rule'; import { aggregateRulesRoute } from './rule/apis/aggregate/aggregate_rules_route'; diff --git a/x-pack/plugins/alerting/server/routes/get_rule.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts similarity index 90% rename from x-pack/plugins/alerting/server/routes/get_rule.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts index 8750e382f7811..f854109f16f1b 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts @@ -6,16 +6,16 @@ */ import { pick } from 'lodash'; -import { getRuleRoute } from './get_rule'; +import { getRuleRoute } from './get_rule_route'; import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { verifyApiAccess } from '../lib/license_api_access'; -import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesClientMock } from '../rules_client.mock'; -import { RuleAction, RuleSystemAction, SanitizedRule } from '../types'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { RuleAction, RuleSystemAction, SanitizedRule } from '../../../../types'; const rulesClient = rulesClientMock.create(); -jest.mock('../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -64,8 +64,8 @@ describe('getRuleRoute', () => { params: { bar: true, }, - createdAt: new Date(), - updatedAt: new Date(), + createdAt: new Date('2020-08-20T19:23:38Z'), + updatedAt: new Date('2020-08-20T19:23:38Z'), actions: [action], consumer: 'bar', name: 'abc', @@ -95,13 +95,13 @@ describe('getRuleRoute', () => { updated_by: mockedAlert.updatedBy, api_key_owner: mockedAlert.apiKeyOwner, muted_alert_ids: mockedAlert.mutedInstanceIds, - created_at: mockedAlert.createdAt, - updated_at: mockedAlert.updatedAt, + created_at: mockedAlert.createdAt.toISOString(), + updated_at: mockedAlert.updatedAt.toISOString(), id: mockedAlert.id, revision: mockedAlert.revision, execution_status: { status: mockedAlert.executionStatus.status, - last_execution_date: mockedAlert.executionStatus.lastExecutionDate, + last_execution_date: mockedAlert.executionStatus.lastExecutionDate.toISOString(), }, actions: [ { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts new file mode 100644 index 0000000000000..7f1b3932e1730 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts @@ -0,0 +1,87 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import type { RuleParamsV1 } from '../../../../../common/routes/rule/response'; +import { Rule } from '../../../../application/rule/types'; +import { + AlertingRequestHandlerContext, + BASE_ALERTING_API_PATH, + INTERNAL_BASE_ALERTING_API_PATH, +} from '../../../../types'; +import { transformRuleToRuleResponseV1 } from '../../transforms'; + +import type { + GetRuleRequestParamsV1, + GetRuleResponseV1, +} from '../../../../../common/routes/rule/apis/get'; +import { getRuleRequestParamsSchemaV1 } from '../../../../../common/routes/rule/apis/get'; + +interface BuildGetRulesRouteParams { + licenseState: ILicenseState; + path: string; + router: IRouter; + excludeFromPublicApi?: boolean; +} +const buildGetRuleRoute = ({ + licenseState, + path, + router, + excludeFromPublicApi = false, +}: BuildGetRulesRouteParams) => { + router.get( + { + path, + validate: { + params: getRuleRequestParamsSchemaV1, + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesClient = (await context.alerting).getRulesClient(); + const params: GetRuleRequestParamsV1 = req.params; + + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + const rule: Rule = (await rulesClient.get({ + id: params.id, + excludeFromPublicApi, + includeSnoozeData: true, + })) as Rule; + + const response: GetRuleResponseV1 = { + body: transformRuleToRuleResponseV1(rule), + }; + return res.ok(response); + }) + ) + ); +}; + +export const getRuleRoute = ( + router: IRouter, + licenseState: ILicenseState +) => + buildGetRuleRoute({ + excludeFromPublicApi: true, + licenseState, + path: `${BASE_ALERTING_API_PATH}/rule/{id}`, + router, + }); + +export const getInternalRuleRoute = ( + router: IRouter, + licenseState: ILicenseState +) => + buildGetRuleRoute({ + excludeFromPublicApi: false, + licenseState, + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}`, + router, + }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts index b11096cd9343b..bd6c8e144e91c 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts @@ -102,8 +102,8 @@ describe('resolveRuleRoute', () => { id: mockedRule.id, revision: mockedRule.revision, execution_status: { - status: mockedRule.executionStatus.status, - last_execution_date: mockedRule.executionStatus.lastExecutionDate.toISOString(), + status: mockedRule.executionStatus!.status, + last_execution_date: mockedRule.executionStatus!.lastExecutionDate.toISOString(), }, actions: [ { diff --git a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index 30bbf77c45ba3..ee4a3a6d14c0f 100644 --- a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -115,15 +115,19 @@ export const transformRuleToRuleResponse = ( ...(rule.notifyWhen !== undefined ? { notify_when: rule.notifyWhen } : {}), muted_alert_ids: rule.mutedInstanceIds, ...(rule.scheduledTaskId !== undefined ? { scheduled_task_id: rule.scheduledTaskId } : {}), - execution_status: { - status: rule.executionStatus.status, - ...(rule.executionStatus.error ? { error: rule.executionStatus.error } : {}), - ...(rule.executionStatus.warning ? { warning: rule.executionStatus.warning } : {}), - last_execution_date: rule.executionStatus.lastExecutionDate?.toISOString(), - ...(rule.executionStatus.lastDuration !== undefined - ? { last_duration: rule.executionStatus.lastDuration } - : {}), - }, + ...(rule.executionStatus + ? { + execution_status: { + status: rule.executionStatus.status, + ...(rule.executionStatus.error ? { error: rule.executionStatus.error } : {}), + ...(rule.executionStatus.warning ? { warning: rule.executionStatus.warning } : {}), + last_execution_date: rule.executionStatus.lastExecutionDate?.toISOString(), + ...(rule.executionStatus.lastDuration !== undefined + ? { last_duration: rule.executionStatus.lastDuration } + : {}), + }, + } + : {}), ...(rule.monitoring ? { monitoring: transformMonitoring(rule.monitoring) } : {}), ...(rule.snoozeSchedule ? { snooze_schedule: rule.snoozeSchedule } : {}), ...(rule.activeSnoozes ? { active_snoozes: rule.activeSnoozes } : {}), diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get.ts b/x-pack/plugins/alerting/server/rules_client/methods/get.ts deleted file mode 100644 index 3fb3a9e2e43c6..0000000000000 --- a/x-pack/plugins/alerting/server/rules_client/methods/get.ts +++ /dev/null @@ -1,79 +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 { AlertConsumers } from '@kbn/rule-data-utils'; - -import { RawRule, SanitizedRule, RuleTypeParams, SanitizedRuleWithLegacyId } from '../../types'; -import { ReadOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { getAlertFromRaw } from '../lib/get_alert_from_raw'; -import { RulesClientContext } from '../types'; -import { formatLegacyActions } from '../lib'; -import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; - -export interface GetParams { - id: string; - includeLegacyId?: boolean; - includeSnoozeData?: boolean; - excludeFromPublicApi?: boolean; -} - -export async function get( - context: RulesClientContext, - { - id, - includeLegacyId = false, - includeSnoozeData = false, - excludeFromPublicApi = false, - }: GetParams -): Promise | SanitizedRuleWithLegacyId> { - const result = await context.unsecuredSavedObjectsClient.get(RULE_SAVED_OBJECT_TYPE, id); - try { - await context.authorization.ensureAuthorized({ - ruleTypeId: result.attributes.alertTypeId, - consumer: result.attributes.consumer, - operation: ReadOperations.Get, - entity: AlertingAuthorizationEntity.Rule, - }); - } catch (error) { - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.GET, - savedObject: { type: RULE_SAVED_OBJECT_TYPE, id }, - error, - }) - ); - throw error; - } - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.GET, - savedObject: { type: RULE_SAVED_OBJECT_TYPE, id }, - }) - ); - const rule = getAlertFromRaw( - context, - result.id, - result.attributes.alertTypeId, - result.attributes, - result.references, - includeLegacyId, - excludeFromPublicApi, - includeSnoozeData - ); - - // format legacy actions for SIEM rules - if (result.attributes.consumer === AlertConsumers.SIEM) { - const [migratedRule] = await formatLegacyActions([rule], { - savedObjectsClient: context.unsecuredSavedObjectsClient, - logger: context.logger, - }); - - return migratedRule; - } - - return rule; -} diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts index 9ff65893da3a0..3640dbcf62c40 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts @@ -19,7 +19,7 @@ import { IExecutionErrorsResult } from '../../../common'; import { formatExecutionErrorsResult } from '../../lib/format_execution_log_errors'; import { parseDate } from '../common'; import { RulesClientContext } from '../types'; -import { get } from './get'; +import { getRule } from '../../application/rule/methods/get/get_rule'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; const actionErrorLogDefaultFilter = @@ -41,7 +41,7 @@ export async function getActionErrorLog( { id, dateStart, dateEnd, filter, page, perPage, sort }: GetActionErrorLogByIdParams ): Promise { context.logger.debug(`getActionErrorLog(): getting action error logs for rule ${id}`); - const rule = (await get(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; + const rule = (await getRule(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; try { await context.authorization.ensureAuthorized({ diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_alert_state.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_alert_state.ts index 57b39f31282a1..d9121fef0be4c 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_alert_state.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_alert_state.ts @@ -10,7 +10,7 @@ import { RuleTaskState } from '../../types'; import { taskInstanceToAlertTaskInstance } from '../../task_runner/alert_task_instance'; import { ReadOperations, AlertingAuthorizationEntity } from '../../authorization'; import { RulesClientContext } from '../types'; -import { get } from './get'; +import { getRule } from '../../application/rule/methods/get/get_rule'; export interface GetAlertStateParams { id: string; @@ -19,7 +19,7 @@ export async function getAlertState( context: RulesClientContext, { id }: GetAlertStateParams ): Promise { - const rule = await get(context, { id }); + const rule = await getRule(context, { id }); await context.authorization.ensureAuthorized({ ruleTypeId: rule.alertTypeId, consumer: rule.consumer, diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_alert_summary.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_alert_summary.ts index 7739b03372007..27af513ae663c 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_alert_summary.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_alert_summary.ts @@ -12,7 +12,7 @@ import { alertSummaryFromEventLog } from '../../lib/alert_summary_from_event_log import { parseDuration } from '../../../common/parse_duration'; import { parseDate } from '../common'; import { RulesClientContext } from '../types'; -import { get } from './get'; +import { getRule } from '../../application/rule/methods/get/get_rule'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; export interface GetAlertSummaryParams { @@ -26,7 +26,7 @@ export async function getAlertSummary( { id, dateStart, numberOfExecutions }: GetAlertSummaryParams ): Promise { context.logger.debug(`getAlertSummary(): getting alert ${id}`); - const rule = (await get(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; + const rule = (await getRule(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; await context.authorization.ensureAuthorized({ ruleTypeId: rule.alertTypeId, diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts index c063b8f90c614..082071ead79e5 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts @@ -19,7 +19,7 @@ import { } from '../../lib/get_execution_log_aggregation'; import { RulesClientContext } from '../types'; import { parseDate } from '../common'; -import { get } from './get'; +import { getRule } from '../../application/rule/methods/get/get_rule'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; export interface GetRuleExecutionKPIParams { @@ -41,7 +41,7 @@ export async function getRuleExecutionKPI( { id, dateStart, dateEnd, filter }: GetRuleExecutionKPIParams ) { context.logger.debug(`getRuleExecutionKPI(): getting execution KPI for rule ${id}`); - const rule = (await get(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; + const rule = (await getRule(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; try { // Make sure user has access to this rule diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts index f240b257bae6e..f154a8e840be2 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts @@ -21,7 +21,7 @@ import { import { IExecutionLogResult } from '../../../common'; import { parseDate } from '../common'; import { RulesClientContext } from '../types'; -import { get } from './get'; +import { getRule } from '../../application/rule/methods/get/get_rule'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; export interface GetExecutionLogByIdParams { @@ -49,7 +49,7 @@ export async function getExecutionLogForRule( { id, dateStart, dateEnd, filter, page, perPage, sort }: GetExecutionLogByIdParams ): Promise { context.logger.debug(`getExecutionLogForRule(): getting execution log for rule ${id}`); - const rule = (await get(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; + const rule = (await getRule(context, { id, includeLegacyId: true })) as SanitizedRuleWithLegacyId; try { // Make sure user has access to this rule diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 942d4c4411091..35706e73c8b41 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -15,7 +15,7 @@ import { createRule, CreateRuleParams } from '../application/rule/methods/create import { updateRule, UpdateRuleParams } from '../application/rule/methods/update'; import { snoozeRule, SnoozeRuleOptions } from '../application/rule/methods/snooze'; import { unsnoozeRule, UnsnoozeParams } from '../application/rule/methods/unsnooze'; -import { get, GetParams } from './methods/get'; +import { getRule, GetRuleParams } from '../application/rule/methods/get'; import { resolveRule, ResolveParams } from '../application/rule/methods/resolve'; import { getAlertState, GetAlertStateParams } from './methods/get_alert_state'; import { getAlertSummary, GetAlertSummaryParams } from './methods/get_alert_summary'; @@ -134,8 +134,8 @@ export class RulesClient { public delete = (params: { id: string }) => deleteRule(this.context, params); public find = (params?: FindParams) => find(this.context, params); - public get = (params: GetParams) => - get(this.context, params); + public get = (params: GetRuleParams) => + getRule(this.context, params); public resolve = (params: ResolveParams) => resolveRule(this.context, params); public update = (params: UpdateRuleParams) => diff --git a/x-pack/plugins/alerting/server/rules_client/tests/get_alert_state.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/get_alert_state.test.ts index 20d04cae35e97..c1a1824066efe 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/get_alert_state.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/get_alert_state.test.ts @@ -80,6 +80,10 @@ describe('getAlertState()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [ { group: 'default', @@ -116,11 +120,12 @@ describe('getAlertState()', () => { await rulesClient.getAlertState({ id: '1' }); expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1); expect(unsecuredSavedObjectsClient.get.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); + Array [ + "alert", + "1", + undefined, + ] + `); }); test('gets the underlying task from TaskManager', async () => { @@ -137,6 +142,10 @@ describe('getAlertState()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [ { group: 'default', @@ -195,6 +204,10 @@ describe('getAlertState()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [], enabled: true, scheduledTaskId, @@ -208,8 +221,7 @@ describe('getAlertState()', () => { await rulesClient.getAlertState({ id: '1' }); - expect(rulesClientParams.logger.warn).toHaveBeenCalledTimes(1); - expect(rulesClientParams.logger.warn).toHaveBeenCalledWith('Task (task-123) not found'); + expect(rulesClientParams.logger.warn).toHaveBeenNthCalledWith(2, 'Task (task-123) not found'); }); test('logs a warning if the taskManager throws an error', async () => { @@ -226,6 +238,10 @@ describe('getAlertState()', () => { params: { bar: true, }, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [], enabled: true, scheduledTaskId, @@ -239,8 +255,8 @@ describe('getAlertState()', () => { await rulesClient.getAlertState({ id: '1' }); - expect(rulesClientParams.logger.warn).toHaveBeenCalledTimes(1); - expect(rulesClientParams.logger.warn).toHaveBeenCalledWith( + expect(rulesClientParams.logger.warn).toHaveBeenNthCalledWith( + 2, 'An error occurred when getting the task state for (task-123): Bad Request' ); }); @@ -257,6 +273,11 @@ describe('getAlertState()', () => { params: { bar: true, }, + enabled: true, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, actions: [ { group: 'default', diff --git a/x-pack/test/functional/es_archives/alerts/data.json b/x-pack/test/functional/es_archives/alerts/data.json index 87081086064b9..e5dd170df284b 100644 --- a/x-pack/test/functional/es_archives/alerts/data.json +++ b/x-pack/test/functional/es_archives/alerts/data.json @@ -27,6 +27,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-06-17T15:35:38.497Z", "updatedBy": "elastic" }, "migrationVersion": { @@ -133,6 +134,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-09-22T15:16:07.451Z", "updatedBy": "elastic" }, "migrationVersion": { @@ -210,6 +212,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-06-17T15:35:38.497Z", "updatedBy": "elastic" }, "migrationVersion": { @@ -306,6 +309,7 @@ "foo" ], "throttle": "1m", + "updatedAt": "2020-09-22T15:16:07.451Z", "updatedBy": null }, "migrationVersion": { @@ -372,6 +376,7 @@ "apiKey" : null, "createdBy" : "elastic", "updatedBy" : "elastic", + "updatedAt" : "2021-07-27T20:42:55.896Z", "createdAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], @@ -431,6 +436,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-09-22T15:16:07.451Z", "updatedBy": "elastic" }, "migrationVersion": { @@ -478,6 +484,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt" : "2021-07-27T20:42:55.896Z", + "updatedAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], "scheduledTaskId" : null, @@ -518,6 +525,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt" : "2021-07-27T20:42:55.896Z", + "updatedAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], "scheduledTaskId" : null, @@ -558,6 +566,7 @@ "apiKey" : null, "createdBy" : "elastic", "updatedBy" : "elastic", + "updatedAt" : "2021-07-27T20:42:55.896Z", "createdAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], @@ -598,6 +607,7 @@ "apiKey" : null, "createdBy" : "elastic", "updatedBy" : "elastic", + "updatedAt" : "2021-07-27T20:42:55.896Z", "createdAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], @@ -647,6 +657,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt" : "2021-07-27T20:42:55.896Z", + "updatedAt" : "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], "scheduledTaskId" : null, @@ -740,6 +751,7 @@ "createdBy":"3270256467", "updatedBy":"3270256467", "createdAt":"2022-02-16T01:24:02.121Z", + "updatedAt":"2021-07-27T20:42:55.896Z", "muteAll":true, "mutedInstanceIds":[ @@ -833,6 +845,7 @@ "createdBy":"3270256467", "updatedBy":"3270256467", "createdAt":"2022-02-16T01:25:02.121Z", + "updatedAt":"2022-02-16T01:25:02.121Z", "muteAll":true, "mutedInstanceIds":[ @@ -875,6 +888,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt" : "2021-07-27T20:42:55.896Z", + "updatedAt": "2021-07-27T20:42:55.896Z", "muteAll" : false, "mutedInstanceIds" : [ ], "scheduledTaskId" : null, @@ -926,6 +940,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt": "2022-03-26T16:04:50.698Z", + "updatedAt": "2022-03-26T16:04:50.698Z", "muteAll": false, "mutedInstanceIds": [], "scheduledTaskId": "776cb5c0-ad1e-11ec-ab9e-5f5932f4fad8", @@ -1023,6 +1038,7 @@ "createdBy":"elastic", "updatedBy":"elastic", "createdAt":"2021-07-27T20:42:55.896Z", + "updatedAt":"2021-07-27T20:42:55.896Z", "muteAll":true, "mutedInstanceIds":[ @@ -1082,6 +1098,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt": "2022-03-26T16:04:50.698Z", + "updatedAt":"2022-03-26T16:04:50.698Z", "muteAll": false, "mutedInstanceIds": [], "scheduledTaskId": "c8b39c29-d860-43b6-8817-b8058d80ddbc", @@ -1133,6 +1150,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt": "2022-03-26T16:04:50.698Z", + "updatedAt": "2022-03-26T16:04:50.698Z", "muteAll": false, "mutedInstanceIds": [], "scheduledTaskId": "62c62b7f-8bf3-4104-a064-6247b7bda44f", @@ -1184,6 +1202,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt": "2022-03-26T16:04:50.698Z", + "updatedAt": "2022-03-26T16:04:50.698Z", "muteAll": false, "mutedInstanceIds": [], "scheduledTaskId": "f0d13f4d-35ae-4554-897a-6392e97bb84c", @@ -1225,6 +1244,7 @@ "tags": [], "throttle": null, "updatedBy": "elastic", + "updatedAt": "2022-08-24T19:02:30.889Z", "isSnoozedUntil": "2022-08-24T19:05:49.817Z" }, "migrationVersion": { @@ -1263,6 +1283,7 @@ "tags": [], "throttle": null, "updatedBy": "elastic", + "updatedAt": "2022-08-24T19:02:30.889Z", "isSnoozedUntil": "2022-08-24T19:05:49.817Z", "executionStatus": { "status": "ok", @@ -1321,6 +1342,7 @@ "tags": [], "throttle": null, "updatedBy": "elastic", + "updatedAt": "2022-08-24T19:02:30.889Z", "isSnoozedUntil": "2022-08-24T19:05:49.817Z", "executionStatus": { "status": "warning", @@ -1394,6 +1416,7 @@ "createdBy" : "elastic", "updatedBy" : "elastic", "createdAt": "2023-01-26T14:20:13.449Z", + "updatedAt": "2023-01-26T14:20:13.449Z", "muteAll": false, "mutedInstanceIds": [], "scheduledTaskId": "8bd01ff0-9d84-11ed-994d-f1971f849da5", @@ -1457,6 +1480,7 @@ "createdBy":"elastic", "updatedBy":"elastic", "createdAt":"2023-03-27T20:42:55.896Z", + "updatedAt":"2023-03-27T20:42:55.896Z", "muteAll":true, "mutedInstanceIds":[], "scheduledTaskId":null, diff --git a/x-pack/test/functional/es_archives/alerts/mappings.json b/x-pack/test/functional/es_archives/alerts/mappings.json index 2e64004634fa6..575d0dd167987 100644 --- a/x-pack/test/functional/es_archives/alerts/mappings.json +++ b/x-pack/test/functional/es_archives/alerts/mappings.json @@ -173,6 +173,9 @@ "updatedBy": { "type": "keyword" }, + "updatedAt": { + "type": "date" + }, "isSnoozedUntil": { "type": "date" }, diff --git a/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/data.json b/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/data.json index 6cbc4d402f87d..531bcbad84ba0 100644 --- a/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/data.json +++ b/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/data.json @@ -27,6 +27,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-06-17T15:35:38.497Z", "updatedBy": "elastic" }, "migrationVersion": { @@ -69,6 +70,7 @@ "tags": [ ], "throttle": null, + "updatedAt": "2020-06-17T15:35:38.497Z", "updatedBy": "elastic" }, "migrationVersion": { diff --git a/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/mappings.json b/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/mappings.json index babc00babc838..3349aeb7314ea 100644 --- a/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/mappings.json +++ b/x-pack/test/functional/es_archives/rules_scheduled_task_id/rules/mappings.json @@ -172,6 +172,9 @@ }, "updatedBy": { "type": "keyword" + }, + "updatedAt": { + "type": "date" } } }, From 4b4c573904b35650701a695767d560ee4f3917f3 Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:28:22 +0900 Subject: [PATCH 042/104] [RAM][HTTP versioning] Version Bulk Enable Route (#179778) ## Summary Parent Issue: https://github.com/elastic/kibana/issues/157883 Issue: https://github.com/elastic/kibana/issues/179669 Versions the `PATCH /internal/alerting/rules/_bulk_enable` endpoint with added input and output validation. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../routes/rule/apis/bulk_enable/index.ts | 15 ++ .../rule/apis/bulk_enable/schemas/latest.ts | 8 + .../rule/apis/bulk_enable/schemas/v1.ts | 13 ++ .../rule/apis/bulk_enable/types/latest.ts | 8 + .../routes/rule/apis/bulk_enable/types/v1.ts | 30 +++ .../bulk_enable/bulk_enable_rules.test.ts} | 28 +-- .../methods/bulk_enable/bulk_enable_rules.ts} | 98 ++++++---- .../rule/methods/bulk_enable/index.ts | 10 + .../schemas/bulk_enable_rules_schemas.ts | 13 ++ .../rule/methods/bulk_enable/schemas/index.ts | 8 + .../types/bulk_enable_rules_types.ts | 31 +++ .../rule/methods/bulk_enable/types/index.ts | 8 + .../plugins/alerting/server/routes/index.ts | 2 +- .../bulk_enable_rules_route.test.ts} | 105 +++++++---- .../bulk_enable/bulk_enable_rules_route.ts} | 40 ++-- .../rule/apis/bulk_enable/transforms/index.ts | 10 + .../transform_bulk_enable_response/latest.ts | 8 + .../transform_bulk_enable_response/v1.test.ts | 177 ++++++++++++++++++ .../transform_bulk_enable_response/v1.ts | 23 +++ .../server/rules_client/rules_client.ts | 6 +- .../server/rules_client/tests/test_helpers.ts | 56 ++++-- .../group3/tests/alerting/bulk_enable.ts | 44 +++-- .../tests/alerting/user_managed_api_key.ts | 4 +- 23 files changed, 604 insertions(+), 141 deletions(-) create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/index.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/v1.ts rename x-pack/plugins/alerting/server/{rules_client/tests/bulk_enable.test.ts => application/rule/methods/bulk_enable/bulk_enable_rules.test.ts} (96%) rename x-pack/plugins/alerting/server/{rules_client/methods/bulk_enable.ts => application/rule/methods/bulk_enable/bulk_enable_rules.ts} (77%) create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/bulk_enable_rules_schemas.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/bulk_enable_rules_types.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/index.ts rename x-pack/plugins/alerting/server/routes/{bulk_enable_rules.test.ts => rule/apis/bulk_enable/bulk_enable_rules_route.test.ts} (67%) rename x-pack/plugins/alerting/server/routes/{bulk_enable_rules.ts => rule/apis/bulk_enable/bulk_enable_rules_route.ts} (55%) create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/index.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/latest.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.test.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/index.ts new file mode 100644 index 0000000000000..e9949179e764f --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { bulkEnableBodySchema } from './schemas/latest'; +export type { BulkEnableRulesRequestBody, BulkEnableRulesResponse } from './types/latest'; + +export { bulkEnableBodySchema as bulkEnableBodySchemaV1 } from './schemas/v1'; +export type { + BulkEnableRulesRequestBody as BulkEnableRulesRequestBodyV1, + BulkEnableRulesResponse as BulkEnableRulesResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/v1.ts new file mode 100644 index 0000000000000..f0300ef927f81 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/schemas/v1.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const bulkEnableBodySchema = schema.object({ + filter: schema.maybe(schema.string()), + ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/v1.ts new file mode 100644 index 0000000000000..49a78d2f82615 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_enable/types/v1.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { RuleParamsV1, RuleResponseV1 } from '../../../response'; +import { bulkEnableBodySchemaV1 } from '..'; + +export type BulkEnableRulesRequestBody = TypeOf; + +interface BulkEnableOperationError { + message: string; + status?: number; + rule: { + id: string; + name: string; + }; +} + +export interface BulkEnableRulesResponse { + body: { + rules: Array>; + errors: BulkEnableOperationError[]; + total: number; + task_ids_failed_to_be_enabled: string[]; + }; +} diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_enable.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.test.ts similarity index 96% rename from x-pack/plugins/alerting/server/rules_client/tests/bulk_enable.test.ts rename to x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.test.ts index de465316ec14f..9140fcd361769 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/bulk_enable.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.test.ts @@ -5,21 +5,21 @@ * 2.0. */ import { AlertConsumers } from '@kbn/rule-data-utils'; -import { RulesClient, ConstructorOptions } from '../rules_client'; +import { RulesClient, ConstructorOptions } from '../../../../rules_client/rules_client'; import { savedObjectsClientMock, savedObjectsRepositoryMock, uiSettingsServiceMock, } from '@kbn/core/server/mocks'; import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; -import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; -import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; +import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock'; +import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; -import { AlertingAuthorization } from '../../authorization/alerting_authorization'; +import { AlertingAuthorization } from '../../../../authorization/alerting_authorization'; import { ActionsAuthorization } from '@kbn/actions-plugin/server'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { getBeforeSetup, setGlobalDate } from './lib'; +import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib'; import { loggerMock } from '@kbn/logging-mocks'; import { BulkUpdateTaskResult } from '@kbn/task-manager-plugin/server/task_scheduling'; import { ActionsClient } from '@kbn/actions-plugin/server'; @@ -41,24 +41,24 @@ import { disabledRuleForBulkDisable1, siemRuleForBulkOps1, siemRuleForBulkOps2, -} from './test_helpers'; +} from '../../../../rules_client/tests/test_helpers'; import { TaskStatus } from '@kbn/task-manager-plugin/server'; -import { migrateLegacyActions } from '../lib'; -import { ConnectorAdapterRegistry } from '../../connector_adapters/connector_adapter_registry'; -import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; -import { backfillClientMock } from '../../backfill_client/backfill_client.mock'; +import { migrateLegacyActions } from '../../../../rules_client/lib'; +import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; +import { ConnectorAdapterRegistry } from '../../../../connector_adapters/connector_adapter_registry'; +import { backfillClientMock } from '../../../../backfill_client/backfill_client.mock'; -jest.mock('../lib/siem_legacy_actions/migrate_legacy_actions', () => { +jest.mock('../../../../rules_client/lib/siem_legacy_actions/migrate_legacy_actions', () => { return { migrateLegacyActions: jest.fn(), }; }); -jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ +jest.mock('../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ bulkMarkApiKeysForInvalidation: jest.fn(), })); -jest.mock('../../application/rule/methods/get_schedule_frequency', () => ({ +jest.mock('../get_schedule_frequency', () => ({ validateScheduleLimit: jest.fn(), })); @@ -171,7 +171,7 @@ describe('bulkEnableRules', () => { rulesClientParams.getActionsClient.mockResolvedValue(actionsClient); }); - test('should enable two rule', async () => { + test('should enable two rules', async () => { unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ saved_objects: [enabledRuleForBulkOps1, enabledRuleForBulkOps2], }); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_enable.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.ts similarity index 77% rename from x-pack/plugins/alerting/server/rules_client/methods/bulk_enable.ts rename to x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.ts index 7d029e211b580..159fc0df4ba17 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_enable.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/bulk_enable_rules.ts @@ -6,38 +6,43 @@ */ import pMap from 'p-map'; +import Boom from '@hapi/boom'; import { KueryNode, nodeBuilder } from '@kbn/es-query'; -import { SavedObjectsBulkUpdateObject, SavedObjectsFindResult } from '@kbn/core/server'; +import { + SavedObjectsBulkCreateObject, + SavedObjectsBulkUpdateObject, + SavedObjectsFindResult, +} from '@kbn/core/server'; import { withSpan } from '@kbn/apm-utils'; import { Logger } from '@kbn/core/server'; import { TaskManagerStartContract, TaskStatus } from '@kbn/task-manager-plugin/server'; import { TaskInstanceWithDeprecatedFields } from '@kbn/task-manager-plugin/server/task'; -import { RawRule } from '../../types'; -import { convertRuleIdsToKueryNode } from '../../lib'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; +import { bulkCreateRulesSo } from '../../../../data/rule'; +import { RawRule, RawRuleAction } from '../../../../types'; +import { RuleDomain, RuleParams } from '../../types'; +import { convertRuleIdsToKueryNode } from '../../../../lib'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; import { retryIfBulkOperationConflicts, buildKueryNodeFilter, getAndValidateCommonBulkOptions, -} from '../common'; -import { getRuleCircuitBreakerErrorMessage } from '../../../common'; +} from '../../../../rules_client/common'; +import { getRuleCircuitBreakerErrorMessage, SanitizedRule } from '../../../../../common'; import { getAuthorizationFilter, checkAuthorizationAndGetTotal, - updateMeta, createNewAPIKeySet, migrateLegacyActions, -} from '../lib'; -import { RulesClientContext, BulkOperationError, BulkOptions } from '../types'; -import { validateScheduleLimit } from '../../application/rule/methods/get_schedule_frequency'; -import { RuleAttributes } from '../../data/rule/types'; -import { - transformRuleAttributesToRuleDomain, - transformRuleDomainToRule, -} from '../../application/rule/transforms'; -import type { RuleParams } from '../../application/rule/types'; -import { ruleDomainSchema } from '../../application/rule/schemas'; -import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; + updateMetaAttributes, +} from '../../../../rules_client/lib'; +import { RulesClientContext, BulkOperationError } from '../../../../rules_client/types'; +import { validateScheduleLimit } from '../get_schedule_frequency'; +import { RuleAttributes } from '../../../../data/rule/types'; +import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; +import { BulkEnableRulesParams, BulkEnableRulesResult } from './types'; +import { bulkEnableRulesParamsSchema } from './schemas'; +import { transformRuleAttributesToRuleDomain, transformRuleDomainToRule } from '../../transforms'; +import { ruleDomainSchema } from '../../schemas'; /** * Updating too many rules in parallel can cause the denial of service of the @@ -71,11 +76,17 @@ const getShouldScheduleTask = async ( export const bulkEnableRules = async ( context: RulesClientContext, - options: BulkOptions -) => { - const { ids, filter } = getAndValidateCommonBulkOptions(options); + params: BulkEnableRulesParams +): Promise> => { + const { ids, filter } = getAndValidateCommonBulkOptions(params); const actionsClient = await context.getActionsClient(); + try { + bulkEnableRulesParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating bulk enable rules data - ${error.message}`); + } + const kueryNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : buildKueryNodeFilter(filter); const authorizationFilter = await getAuthorizationFilter(context, { action: 'ENABLE' }); @@ -105,12 +116,12 @@ export const bulkEnableRules = async ( taskManager: context.taskManager, }); - const enabledRules = rules.map(({ id, attributes, references }) => { + const updatedRules = rules.map(({ id, attributes, references }) => { // TODO (http-versioning): alertTypeId should never be null, but we need to // fix the type cast from SavedObjectsBulkUpdateObject to SavedObjectsBulkUpdateObject - // when we are doing the bulk disable and this should fix itself + // when we are doing the bulk delete and this should fix itself const ruleType = context.ruleTypeRegistry.get(attributes.alertTypeId!); - const ruleDomain = transformRuleAttributesToRuleDomain( + const ruleDomain: RuleDomain = transformRuleAttributesToRuleDomain( attributes as RuleAttributes, { id, @@ -125,12 +136,17 @@ export const bulkEnableRules = async ( try { ruleDomainSchema.validate(ruleDomain); } catch (e) { - context.logger.warn(`Error validating bulk enabled rule domain object for id: ${id}, ${e}`); + context.logger.warn(`Error validating bulk enable rule domain object for id: ${id}, ${e}`); } - return transformRuleDomainToRule(ruleDomain); + return ruleDomain; }); - return { errors, rules: enabledRules, total, taskIdsFailedToBeEnabled }; + // // TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed + const updatePublicRules = updatedRules.map((rule: RuleDomain) => { + return transformRuleDomainToRule(rule); + }) as Array>; + + return { errors, rules: updatePublicRules, total, taskIdsFailedToBeEnabled }; }; const bulkEnableRulesWithOCC = async ( @@ -145,7 +161,7 @@ const bulkEnableRulesWithOCC = async ( type: 'rules', }, async () => - await context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + await context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( { filter: filter ? nodeBuilder.and([filter, additionalFilter]) : additionalFilter, type: RULE_SAVED_OBJECT_TYPE, @@ -155,8 +171,8 @@ const bulkEnableRulesWithOCC = async ( ) ); - const rulesFinderRules: Array> = []; - const rulesToEnable: Array> = []; + const rulesFinderRules: Array> = []; + const rulesToEnable: Array> = []; const tasksToSchedule: TaskInstanceWithDeprecatedFields[] = []; const errors: BulkOperationError[] = []; const ruleNameToRuleIdMapping: Record = {}; @@ -207,14 +223,15 @@ const bulkEnableRulesWithOCC = async ( ruleNameToRuleIdMapping[rule.id] = rule.attributes.name; } + // TODO (http-versioning) Remove RawRuleAction and RawRule casts const migratedActions = await migrateLegacyActions(context, { ruleId: rule.id, - actions: rule.attributes.actions, + actions: rule.attributes.actions as RawRuleAction[], references: rule.references, - attributes: rule.attributes, + attributes: rule.attributes as RawRule, }); - const updatedAttributes = updateMeta(context, { + const updatedAttributes = updateMetaAttributes(context, { ...rule.attributes, ...(!rule.attributes.apiKey && (await createNewAPIKeySet(context, { @@ -315,12 +332,21 @@ const bulkEnableRulesWithOCC = async ( const result = await withSpan( { name: 'unsecuredSavedObjectsClient.bulkCreate', type: 'rules' }, () => - context.unsecuredSavedObjectsClient.bulkCreate(rulesToEnable, { - overwrite: true, + // TODO (http-versioning): for whatever reasoning we are using SavedObjectsBulkUpdateObject + // everywhere when it should be SavedObjectsBulkCreateObject. We need to fix it in + // bulk_disable, bulk_enable, etc. to fix this cast + bulkCreateRulesSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + bulkCreateRuleAttributes: rulesToEnable as Array< + SavedObjectsBulkCreateObject + >, + savedObjectsBulkCreateOptions: { + overwrite: true, + }, }) ); - const rules: Array> = []; + const rules: Array> = []; const taskIdsToEnable: string[] = []; result.saved_objects.forEach((rule) => { diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/index.ts new file mode 100644 index 0000000000000..444485f029392 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { BulkEnableRulesParams, BulkEnableRulesError, BulkEnableRulesResult } from './types'; + +export { bulkEnableRules } from './bulk_enable_rules'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/bulk_enable_rules_schemas.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/bulk_enable_rules_schemas.ts new file mode 100644 index 0000000000000..6792e63c042d5 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/bulk_enable_rules_schemas.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const bulkEnableRulesParamsSchema = schema.object({ + filter: schema.maybe(schema.string()), + ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/index.ts new file mode 100644 index 0000000000000..b2b92ee5a57e1 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './bulk_enable_rules_schemas'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/bulk_enable_rules_types.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/bulk_enable_rules_types.ts new file mode 100644 index 0000000000000..c33e2ef964915 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/bulk_enable_rules_types.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RuleParams } from '../../../types/rule'; +import { SanitizedRule } from '../../../../../types'; + +export interface BulkEnableRulesParams { + filter?: string; + ids?: string[]; +} + +export interface BulkEnableRulesError { + message: string; + status?: number; + rule: { + id: string; + name: string; + }; +} + +// TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed +export interface BulkEnableRulesResult { + rules: Array>; + errors: BulkEnableRulesError[]; + total: number; + taskIdsFailedToBeEnabled: string[]; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/index.ts new file mode 100644 index 0000000000000..9e031635dcb58 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_enable/types/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './bulk_enable_rules_types'; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 2f0f773a995d3..fc07b8dbeb6e8 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -41,7 +41,7 @@ import { snoozeRuleRoute } from './rule/apis/snooze'; import { unsnoozeRuleRoute } from './rule/apis/unsnooze'; import { runSoonRoute } from './run_soon'; import { bulkDeleteRulesRoute } from './rule/apis/bulk_delete/bulk_delete_rules_route'; -import { bulkEnableRulesRoute } from './bulk_enable_rules'; +import { bulkEnableRulesRoute } from './rule/apis/bulk_enable/bulk_enable_rules_route'; import { bulkDisableRulesRoute } from './rule/apis/bulk_disable/bulk_disable_rules_route'; import { cloneRuleRoute } from './clone_rule'; import { getFlappingSettingsRoute } from './get_flapping_settings'; diff --git a/x-pack/plugins/alerting/server/routes/bulk_enable_rules.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts similarity index 67% rename from x-pack/plugins/alerting/server/routes/bulk_enable_rules.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts index 1ede4d1895c4f..9a0d22dadc9a4 100644 --- a/x-pack/plugins/alerting/server/routes/bulk_enable_rules.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts @@ -7,18 +7,19 @@ import { httpServiceMock } from '@kbn/core/server/mocks'; import { actionsClientMock } from '@kbn/actions-plugin/server/mocks'; -import { bulkEnableRulesRoute } from './bulk_enable_rules'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesClientMock } from '../rules_client.mock'; -import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled'; -import { verifyApiAccess } from '../lib/license_api_access'; -import { RuleAction, RuleSystemAction } from '../types'; -import { Rule } from '../application/rule/types'; +import { bulkEnableRulesRoute } from './bulk_enable_rules_route'; +import { BulkEnableRulesResult } from '../../../../application/rule/methods/bulk_enable'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { RuleTypeDisabledError } from '../../../../lib/errors/rule_type_disabled'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { RuleAction, RuleSystemAction } from '../../../../types'; +import { Rule, RuleParams } from '../../../../application/rule/types'; const rulesClient = rulesClientMock.create(); -jest.mock('../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -29,6 +30,7 @@ beforeEach(() => { describe('bulkEnableRulesRoute', () => { const bulkEnableRequest = { filter: '' }; const bulkEnableResult = { errors: [], rules: [], total: 1, taskIdsFailedToBeEnabled: [] }; + const bulkEnableResponse = { errors: [], rules: [], total: 1, task_ids_failed_to_be_enabled: [] }; it('should enable rules with proper parameters', async () => { const licenseState = licenseStateMock.create(); @@ -51,7 +53,7 @@ describe('bulkEnableRulesRoute', () => { ); expect(await handler(context, req, res)).toEqual({ - body: bulkEnableResult, + body: bulkEnableResponse, }); expect(rulesClient.bulkEnableRules).toHaveBeenCalledTimes(1); @@ -127,15 +129,15 @@ describe('bulkEnableRulesRoute', () => { }); describe('actions', () => { - const mockedRule: Rule<{}> = { + const mockedRule: Rule = { id: '1', alertTypeId: '1', schedule: { interval: '10s' }, params: { bar: true, }, - createdAt: new Date(), - updatedAt: new Date(), + createdAt: new Date('2020-08-20T19:23:38Z'), + updatedAt: new Date('2020-08-20T19:23:38Z'), actions: [ { group: 'default', @@ -184,7 +186,7 @@ describe('bulkEnableRulesRoute', () => { uuid: '123-456', }; - const mockedRules: Array> = [ + const mockedRules: Array> = [ { ...mockedRule, actions: [action], @@ -208,7 +210,9 @@ describe('bulkEnableRulesRoute', () => { bulkEnableRulesRoute({ router, licenseState }); const [_, handler] = router.patch.mock.calls[0]; - rulesClient.bulkEnableRules.mockResolvedValueOnce(bulkEnableActionsResult); + rulesClient.bulkEnableRules.mockResolvedValueOnce( + bulkEnableActionsResult as BulkEnableRulesResult + ); const [context, req, res] = mockHandlerArguments( { rulesClient, actionsClient }, @@ -221,25 +225,60 @@ describe('bulkEnableRulesRoute', () => { const routeRes = await handler(context, req, res); // @ts-expect-error: body exists - expect(routeRes.body.rules[0].actions).toEqual([ - { - actionTypeId: 'test', - group: 'default', - id: '2', - params: { - foo: true, + expect(routeRes.body).toEqual({ + rules: [ + { + id: '1', + enabled: true, + name: 'abc', + tags: ['foo'], + rule_type_id: '1', + consumer: 'bar', + schedule: { + interval: '10s', + }, + actions: [ + { + group: 'default', + id: '2', + params: { + foo: true, + }, + connector_type_id: 'test', + uuid: '123-456', + }, + { + id: 'system_action-id', + params: { + foo: true, + }, + uuid: '123-456', + connector_type_id: 'test-2', + }, + ], + params: { + bar: true, + }, + created_by: '', + updated_by: '', + created_at: '2020-08-20T19:23:38.000Z', + updated_at: '2020-08-20T19:23:38.000Z', + api_key_owner: '', + throttle: '30s', + mute_all: false, + notify_when: 'onActionGroupChange', + muted_alert_ids: [], + execution_status: { + status: 'unknown', + last_execution_date: '2020-08-20T19:23:38.000Z', + }, + revision: 0, }, - uuid: '123-456', - }, - { - actionTypeId: 'test-2', - id: 'system_action-id', - params: { - foo: true, - }, - uuid: '123-456', - }, - ]); + ], + errors: [], + total: 1, + task_ids_failed_to_be_enabled: [], + }); }); }); }); diff --git a/x-pack/plugins/alerting/server/routes/bulk_enable_rules.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts similarity index 55% rename from x-pack/plugins/alerting/server/routes/bulk_enable_rules.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts index ddfce5905ca4a..9a8210dc8aed8 100644 --- a/x-pack/plugins/alerting/server/routes/bulk_enable_rules.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts @@ -5,11 +5,17 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; import { IRouter } from '@kbn/core/server'; -import { verifyAccessAndContext, handleDisabledApiKeysError } from './lib'; -import { ILicenseState, RuleTypeDisabledError } from '../lib'; -import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { verifyAccessAndContext, handleDisabledApiKeysError } from '../../../lib'; +import { ILicenseState, RuleTypeDisabledError } from '../../../../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types'; +import { + bulkEnableBodySchemaV1, + BulkEnableRulesRequestBodyV1, + BulkEnableRulesResponseV1, +} from '../../../../../common/routes/rule/apis/bulk_enable'; +import { RuleParamsV1 } from '../../../../../common/routes/rule/response'; +import { transformBulkEnableResponseV1 } from './transforms'; export const bulkEnableRulesRoute = ({ router, @@ -22,32 +28,24 @@ export const bulkEnableRulesRoute = ({ { path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/_bulk_enable`, validate: { - body: schema.object({ - filter: schema.maybe(schema.string()), - ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), - }), + body: bulkEnableBodySchemaV1, }, }, handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async (context, req, res) => { const rulesClient = (await context.alerting).getRulesClient(); - const { filter, ids } = req.body; + const body: BulkEnableRulesRequestBodyV1 = req.body; try { - const bulkEnableResults = await rulesClient.bulkEnableRules({ filter, ids }); + const result = await rulesClient.bulkEnableRules({ + filter: body.filter, + ids: body.ids, + }); - const resultBody = { - body: { - ...bulkEnableResults, - // TODO We need to fix this API to return snake case like every other API - rules: bulkEnableResults.rules.map(({ actions, systemActions, ...rule }) => { - return { ...rule, actions: [...actions, ...(systemActions ?? [])] }; - }), - }, - }; - - return res.ok(resultBody); + const response: BulkEnableRulesResponseV1['body'] = + transformBulkEnableResponseV1(result); + return res.ok({ body: response }); } catch (e) { if (e instanceof RuleTypeDisabledError) { return e.sendResponse(res); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/index.ts new file mode 100644 index 0000000000000..ceb6082d41516 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformBulkEnableResponse } from './transform_bulk_enable_response/latest'; + +export { transformBulkEnableResponse as transformBulkEnableResponseV1 } from './transform_bulk_enable_response/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.test.ts new file mode 100644 index 0000000000000..a4acab93ba387 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.test.ts @@ -0,0 +1,177 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { transformBulkEnableResponse } from './v1'; +import { RuleAction, RuleSystemAction } from '../../../../../../../common'; + +describe('transformBulkEnableResponse', () => { + const defaultAction: RuleAction = { + id: '1', + uuid: '111', + params: { foo: 'bar' }, + group: 'default', + actionTypeId: '.test', + frequency: { notifyWhen: 'onThrottleInterval', summary: true, throttle: '1h' }, + alertsFilter: { + query: { dsl: '{test:1}', kql: 'test:1s', filters: [] }, + timeframe: { + days: [1, 2, 3], + hours: { end: '15:00', start: '00:00' }, + timezone: 'UTC', + }, + }, + }; + + const systemAction: RuleSystemAction = { + id: '2', + uuid: '222', + params: { foo: 'bar' }, + actionTypeId: '.test', + }; + + const rule = { + id: '3d534c70-582b-11ec-8995-2b1578a3bc5d', + enabled: true, + name: 'stressing index-threshold 37/200', + tags: [], + alertTypeId: '.index-threshold', + consumer: 'alerts', + schedule: { + interval: '1s', + }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + createdBy: 'elastic', + updatedBy: '2889684073', + createdAt: new Date('2023-08-01T09:16:35.368Z'), + updatedAt: new Date('2023-08-01T09:16:35.368Z'), + notifyWhen: 'onActiveAlert' as const, + throttle: null, + apiKey: null, + apiKeyOwner: '2889684073', + muteAll: false, + mutedInstanceIds: [], + scheduledTaskId: '52125fb0-5895-11ec-ae69-bb65d1a71b72', + executionStatus: { + status: 'ok' as const, + lastExecutionDate: new Date('2023-08-01T09:16:35.368Z'), + lastDuration: 1194, + }, + revision: 0, + }; + it('should transform bulk enable result', () => { + expect( + transformBulkEnableResponse({ + rules: [rule], + errors: [ + { + message: 'test error', + status: 400, + rule: { + id: 'error-rule-id', + name: 'error-rule', + }, + }, + ], + + total: 1, + taskIdsFailedToBeEnabled: ['error-rule-id'], + }) + ).toMatchInlineSnapshot(` + Object { + "errors": Array [ + Object { + "message": "test error", + "rule": Object { + "id": "error-rule-id", + "name": "error-rule", + }, + "status": 400, + }, + ], + "rules": Array [ + Object { + "actions": Array [ + Object { + "alerts_filter": Object { + "query": Object { + "dsl": "{test:1}", + "filters": Array [], + "kql": "test:1s", + }, + "timeframe": Object { + "days": Array [ + 1, + 2, + 3, + ], + "hours": Object { + "end": "15:00", + "start": "00:00", + }, + "timezone": "UTC", + }, + }, + "connector_type_id": ".test", + "frequency": Object { + "notify_when": "onThrottleInterval", + "summary": true, + "throttle": "1h", + }, + "group": "default", + "id": "1", + "params": Object { + "foo": "bar", + }, + "uuid": "111", + }, + Object { + "connector_type_id": ".test", + "id": "2", + "params": Object { + "foo": "bar", + }, + "uuid": "222", + }, + ], + "api_key_owner": "2889684073", + "consumer": "alerts", + "created_at": "2023-08-01T09:16:35.368Z", + "created_by": "elastic", + "enabled": true, + "execution_status": Object { + "last_duration": 1194, + "last_execution_date": "2023-08-01T09:16:35.368Z", + "status": "ok", + }, + "id": "3d534c70-582b-11ec-8995-2b1578a3bc5d", + "mute_all": false, + "muted_alert_ids": Array [], + "name": "stressing index-threshold 37/200", + "notify_when": "onActiveAlert", + "params": Object {}, + "revision": 0, + "rule_type_id": ".index-threshold", + "schedule": Object { + "interval": "1s", + }, + "scheduled_task_id": "52125fb0-5895-11ec-ae69-bb65d1a71b72", + "tags": Array [], + "throttle": null, + "updated_at": "2023-08-01T09:16:35.368Z", + "updated_by": "2889684073", + }, + ], + "task_ids_failed_to_be_enabled": Array [ + "error-rule-id", + ], + "total": 1, + } + `); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.ts new file mode 100644 index 0000000000000..5d0498f751be1 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/transforms/transform_bulk_enable_response/v1.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BulkEnableRulesResponseV1 } from '../../../../../../../common/routes/rule/apis/bulk_enable'; +import { RuleParamsV1 } from '../../../../../../../common/routes/rule/response'; +import { BulkEnableRulesResult } from '../../../../../../application/rule/methods/bulk_enable/types'; +import { transformRuleToRuleResponseV1 } from '../../../../transforms'; +import { Rule, RuleParams } from '../../../../../../application/rule/types'; + +export const transformBulkEnableResponse = ( + response: BulkEnableRulesResult +): BulkEnableRulesResponseV1['body'] => { + return { + rules: response.rules.map((rule) => transformRuleToRuleResponseV1(rule as Rule)), + errors: response.errors, + total: response.total, + task_ids_failed_to_be_enabled: response.taskIdsFailedToBeEnabled, + }; +}; diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 35706e73c8b41..e7ebb9fe2e64e 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -9,7 +9,7 @@ import { getRuleTags, RuleTagsParams } from '../application/rule/methods/tags'; import { MuteAlertParams } from '../application/rule/methods/mute_alert/types'; import { SanitizedRule, RuleTypeParams } from '../types'; import { parseDuration } from '../../common/parse_duration'; -import { RulesClientContext, BulkOptions } from './types'; +import { RulesClientContext } from './types'; import { clone, CloneArguments } from './methods/clone'; import { createRule, CreateRuleParams } from '../application/rule/methods/create'; import { updateRule, UpdateRuleParams } from '../application/rule/methods/update'; @@ -52,7 +52,7 @@ import { bulkEditRules, BulkEditOptions, } from '../application/rule/methods/bulk_edit/bulk_edit_rules'; -import { bulkEnableRules } from './methods/bulk_enable'; +import { bulkEnableRules, BulkEnableRulesParams } from '../application/rule/methods/bulk_enable'; import { updateApiKey } from './methods/update_api_key'; import { enable } from './methods/enable'; import { disable } from './methods/disable'; @@ -160,7 +160,7 @@ export class RulesClient { bulkDeleteRules(this.context, options); public bulkEdit = (options: BulkEditOptions) => bulkEditRules(this.context, options); - public bulkEnableRules = (options: BulkOptions) => bulkEnableRules(this.context, options); + public bulkEnableRules = (params: BulkEnableRulesParams) => bulkEnableRules(this.context, params); public bulkDisableRules = (options: BulkDisableRulesRequestBody) => bulkDisableRules(this.context, options); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/test_helpers.ts b/x-pack/plugins/alerting/server/rules_client/tests/test_helpers.ts index 869b38f1762ac..8177f919f80ff 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/test_helpers.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/test_helpers.ts @@ -61,6 +61,8 @@ export const defaultRuleForBulkDelete = { lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), status: 'pending', }, + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), }, references: [], version: '1', @@ -71,6 +73,10 @@ export const siemRule1 = { attributes: { ...defaultRule.attributes, consumer: AlertConsumers.SIEM, + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, }, id: 'siem-id1', }; @@ -101,6 +107,12 @@ export const enabledRule1 = { enabled: true, scheduledTaskId: 'id1', apiKey: Buffer.from('123:abc').toString('base64'), + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), }, }; @@ -112,6 +124,12 @@ export const enabledRule2 = { enabled: true, scheduledTaskId: 'id2', apiKey: Buffer.from('321:abc').toString('base64'), + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), }, }; @@ -283,6 +301,10 @@ export const disabledRule1 = { enabled: false, scheduledTaskId: 'id1', apiKey: Buffer.from('123:abc').toString('base64'), + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, }, }; @@ -294,6 +316,10 @@ export const disabledRule2 = { enabled: false, scheduledTaskId: 'id2', apiKey: Buffer.from('321:abc').toString('base64'), + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, }, }; @@ -389,35 +415,41 @@ export const disabledRuleForBulkWithAction2 = { export const returnedRule1 = { actions: [], alertTypeId: 'fakeType', - apiKey: 'MTIzOmFiYw==', consumer: 'fakeConsumer', enabled: true, id: 'id1', name: 'fakeName', - notifyWhen: undefined, - params: undefined, + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), schedule: { interval: '5m', }, scheduledTaskId: 'id1', snoozeSchedule: [], + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, }; export const returnedRule2 = { actions: [], alertTypeId: 'fakeType', - apiKey: 'MzIxOmFiYw==', consumer: 'fakeConsumer', enabled: true, id: 'id2', name: 'fakeName', - notifyWhen: undefined, - params: undefined, + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), schedule: { interval: '5m', }, scheduledTaskId: 'id2', snoozeSchedule: [], + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), + status: 'pending', + }, }; export const returnedRuleForBulkOps1 = { @@ -431,8 +463,8 @@ export const returnedRuleForBulkOps1 = { lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), status: 'pending', }, - createdAt: new Date('2019-02-12T21:01:22.479Z'), - updatedAt: new Date('2019-02-12T21:01:22.479Z'), + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), schedule: { interval: '5m', }, @@ -457,8 +489,8 @@ export const returnedRuleForBulkOps2 = { lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), status: 'pending', }, - createdAt: new Date('2019-02-12T21:01:22.479Z'), - updatedAt: new Date('2019-02-12T21:01:22.479Z'), + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), schedule: { interval: '5m', }, @@ -484,8 +516,8 @@ export const returnedRuleForBulkOps3 = { lastExecutionDate: new Date('2019-02-12T21:01:22.000Z'), status: 'pending', }, - createdAt: new Date('2019-02-12T21:01:22.479Z'), - updatedAt: new Date('2019-02-12T21:01:22.479Z'), + createdAt: new Date('2019-02-12T21:01:22.000Z'), + updatedAt: new Date('2019-02-12T21:01:22.000Z'), schedule: { interval: '5m', }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts index d61810bb72fd3..4464535dbcd4d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts @@ -15,7 +15,12 @@ import { getUnauthorizedErrorMessage, } from '../../../../common/lib'; -const defaultSuccessfulResponse = { total: 1, rules: [], errors: [], taskIdsFailedToBeEnabled: [] }; +const defaultSuccessfulResponse = { + total: 1, + rules: [], + errors: [], + task_ids_failed_to_be_enabled: [], +}; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { @@ -81,38 +86,39 @@ export default ({ getService }: FtrProviderContext) => { rules: [ { id: response.body.rules[0].id, - notifyWhen: 'onThrottleInterval', + notify_when: 'onThrottleInterval', enabled: true, name: 'abc', tags: ['foo'], consumer: 'alertsFixture', throttle: '1m', - alertTypeId: 'test.noop', - apiKeyCreatedByUser: false, - apiKeyOwner: response.body.rules[0].apiKeyOwner, - createdBy: 'elastic', - updatedBy: response.body.rules[0].updatedBy, - muteAll: false, - mutedInstanceIds: [], + rule_type_id: 'test.noop', + api_key_created_by_user: false, + api_key_owner: response.body.rules[0].api_key_owner, + created_by: 'elastic', + updated_by: response.body.rules[0].updated_by, + mute_all: false, + muted_alert_ids: [], schedule: { interval: '1m' }, actions: [], params: {}, running: false, - snoozeSchedule: [], - updatedAt: response.body.rules[0].updatedAt, - createdAt: response.body.rules[0].createdAt, + snooze_schedule: [], + updated_at: response.body.rules[0].updated_at, + created_at: response.body.rules[0].created_at, revision: 0, - scheduledTaskId: response.body.rules[0].scheduledTaskId, - executionStatus: { - lastDuration: 0, - lastExecutionDate: response.body.rules[0].executionStatus.lastExecutionDate, + scheduled_task_id: response.body.rules[0].scheduled_task_id, + execution_status: { + last_duration: 0, + last_execution_date: + response.body.rules[0].execution_status.last_execution_date, status: 'pending', }, monitoring: response.body.rules[0].monitoring, }, ], errors: [], - taskIdsFailedToBeEnabled: [], + task_ids_failed_to_be_enabled: [], }); break; default: @@ -566,13 +572,13 @@ export default ({ getService }: FtrProviderContext) => { expect([restAction, restSystemAction]).to.eql([ { id: createdAction.id, - actionTypeId: 'test.noop', + connector_type_id: 'test.noop', group: 'default', params: {}, }, { id: 'system-connector-test.system-action', - actionTypeId: 'test.system-action', + connector_type_id: 'test.system-action', params: {}, }, , diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/user_managed_api_key.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/user_managed_api_key.ts index 77c6efc4e92d8..2ceb14992688c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/user_managed_api_key.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/user_managed_api_key.ts @@ -491,7 +491,7 @@ export default function userManagedApiKeyTest({ getService }: FtrProviderContext .send({ ids: [ruleId] }); expect(response.status).to.eql(200); expect(response.body.rules[0].enabled).to.eql(true); - expect(response.body.rules[0].apiKeyCreatedByUser).to.eql(true); + expect(response.body.rules[0].api_key_created_by_user).to.eql(true); // Ensure AAD isn't broken await checkAAD({ @@ -514,7 +514,7 @@ export default function userManagedApiKeyTest({ getService }: FtrProviderContext .send({ ids: [ruleId] }); expect(response.status).to.eql(200); expect(response.body.rules[0].enabled).to.eql(true); - expect(response.body.rules[0].apiKeyCreatedByUser).to.eql(false); + expect(response.body.rules[0].api_key_created_by_user).to.eql(false); // Ensure AAD isn't broken await checkAAD({ From 5ea747c53de06c6f75eaed15d2ccf070e414ee91 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Tue, 30 Apr 2024 10:07:06 -0400 Subject: [PATCH 043/104] [Canvas] Update limits and change some imports (#182028) updates the `limits.yml` to reflect that Canvas is actually _much_ smaller than it appears. --- packages/kbn-optimizer/limits.yml | 4 ++-- x-pack/plugins/canvas/common/lib/constants.ts | 5 +++-- x-pack/plugins/canvas/public/index.ts | 8 ++++---- x-pack/plugins/canvas/public/lib/loading_indicator.ts | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index f1b24fb01b556..0cbb1eff71a67 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -8,7 +8,7 @@ pageLoadAssetSize: assetManager: 25000 banners: 17946 bfetch: 22837 - canvas: 1066647 + canvas: 29355 cases: 180037 charts: 55000 cloud: 21076 @@ -25,7 +25,7 @@ pageLoadAssetSize: core: 435325 crossClusterReplication: 65408 customIntegrations: 22034 - dashboard: 82025 + dashboard: 52967 dashboardEnhanced: 65646 data: 454087 datasetQuality: 50624 diff --git a/x-pack/plugins/canvas/common/lib/constants.ts b/x-pack/plugins/canvas/common/lib/constants.ts index 187dfc9f15f8d..a142fa9386c11 100644 --- a/x-pack/plugins/canvas/common/lib/constants.ts +++ b/x-pack/plugins/canvas/common/lib/constants.ts @@ -5,10 +5,11 @@ * 2.0. */ -// eslint-disable-next-line @kbn/imports/no_boundary_crossing -import { SHAREABLE_RUNTIME_NAME } from '../../shareable_runtime/constants_static'; import { FilterField } from '../../types'; +// avoid import from shareable_runtime +const SHAREABLE_RUNTIME_NAME = 'kbn_canvas'; + export const CANVAS_TYPE = 'canvas-workpad'; export const CUSTOM_ELEMENT_TYPE = 'canvas-element'; export const TEMPLATE_TYPE = `${CANVAS_TYPE}-template`; diff --git a/x-pack/plugins/canvas/public/index.ts b/x-pack/plugins/canvas/public/index.ts index 5c2780b88d124..3d70a6df05fad 100644 --- a/x-pack/plugins/canvas/public/index.ts +++ b/x-pack/plugins/canvas/public/index.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/public'; -import { CoreStart } from '@kbn/core/public'; -import { CanvasServices } from './services'; -import { CanvasSetup, CanvasStart, CanvasStartDeps, CanvasPlugin } from './plugin'; +import type { PluginInitializerContext } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; +import type { CanvasServices } from './services'; +import { type CanvasSetup, type CanvasStart, type CanvasStartDeps, CanvasPlugin } from './plugin'; export type { CanvasSetup, CanvasStart }; diff --git a/x-pack/plugins/canvas/public/lib/loading_indicator.ts b/x-pack/plugins/canvas/public/lib/loading_indicator.ts index 920e732b21bb2..31ffcdd0e3895 100644 --- a/x-pack/plugins/canvas/public/lib/loading_indicator.ts +++ b/x-pack/plugins/canvas/public/lib/loading_indicator.ts @@ -5,8 +5,8 @@ * 2.0. */ -import * as Rx from 'rxjs'; import { CoreStart } from '@kbn/core/public'; +import { BehaviorSubject } from 'rxjs'; let isActive = false; @@ -15,7 +15,7 @@ export interface LoadingIndicatorInterface { hide: () => void; } -const loadingCount$ = new Rx.BehaviorSubject(0); +const loadingCount$ = new BehaviorSubject(0); export const initLoadingIndicator = (addLoadingCount: CoreStart['http']['addLoadingCountSource']) => addLoadingCount(loadingCount$); From b8d8c737e6cc7889c19a6e7984d618bf378ee617 Mon Sep 17 00:00:00 2001 From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:20:28 +0100 Subject: [PATCH 044/104] [Console Monaco Migration] Fix issue with different themes (#180321) Fixes https://github.com/elastic/kibana/issues/180218 ## Summary This PR fixes the highlighting issue in the Monaco editor that is caused when using a theme in the output panel that is different from the theme in the editor. This fix is implemented by unifying the themes for both editors into one. The PR also fixes the issue with Console theme overwriting theme in other code editors (e.g. embeddable Console in the index detail tabs) by reusing the `euiTheme`. Note: This solution changes some of the original highlighting colors in Console (e.g. comments were green and now they are grey, background color is also different now). We might be able to fix the text colors by specifying unique token names in the Console language (e.g. using `consoleComment` instead of `comment` token name). cc: @yuliacech https://github.com/elastic/kibana/assets/59341489/d77d4ea3-61b5-43fa-81ef-7e4ac239aadd https://github.com/elastic/kibana/assets/59341489/1dab2eca-08e5-421b-acd4-38e0b3d91a3e Screenshot 2024-04-22 at 15 34 45 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-monaco/index.ts | 1 - packages/kbn-monaco/src/console/constants.ts | 1 - packages/kbn-monaco/src/console/index.ts | 9 +--- packages/kbn-monaco/src/console/theme.ts | 44 ++++++++++++++++ .../src/console/theme/editor_theme.ts | 31 ------------ .../kbn-monaco/src/console/theme/index.ts | 10 ---- .../src/console/theme/output_theme.ts | 17 ------- .../kbn-monaco/src/console/theme/shared.ts | 50 ------------------- packages/kbn-monaco/src/register_globals.ts | 10 +--- packages/kbn-monaco/tsconfig.json | 2 +- .../editor/monaco/monaco_editor_output.tsx | 5 +- src/plugins/console/public/styles/_app.scss | 1 + 12 files changed, 52 insertions(+), 129 deletions(-) create mode 100644 packages/kbn-monaco/src/console/theme.ts delete mode 100644 packages/kbn-monaco/src/console/theme/editor_theme.ts delete mode 100644 packages/kbn-monaco/src/console/theme/index.ts delete mode 100644 packages/kbn-monaco/src/console/theme/output_theme.ts delete mode 100644 packages/kbn-monaco/src/console/theme/shared.ts diff --git a/packages/kbn-monaco/index.ts b/packages/kbn-monaco/index.ts index fad82d4d4a143..e02ae6dbdfe16 100644 --- a/packages/kbn-monaco/index.ts +++ b/packages/kbn-monaco/index.ts @@ -36,7 +36,6 @@ export { CONSOLE_LANG_ID, CONSOLE_OUTPUT_LANG_ID, CONSOLE_THEME_ID, - CONSOLE_OUTPUT_THEME_ID, getParsedRequestsProvider, ConsoleParsedRequestsProvider, } from './src/console'; diff --git a/packages/kbn-monaco/src/console/constants.ts b/packages/kbn-monaco/src/console/constants.ts index c6563efba93ac..ed29ebd93f10a 100644 --- a/packages/kbn-monaco/src/console/constants.ts +++ b/packages/kbn-monaco/src/console/constants.ts @@ -9,5 +9,4 @@ export const CONSOLE_LANG_ID = 'console'; export const CONSOLE_THEME_ID = 'consoleTheme'; export const CONSOLE_OUTPUT_LANG_ID = 'consoleOutput'; -export const CONSOLE_OUTPUT_THEME_ID = 'consoleOutputTheme'; export const CONSOLE_POSTFIX = '.console'; diff --git a/packages/kbn-monaco/src/console/index.ts b/packages/kbn-monaco/src/console/index.ts index 00f6cb68de64a..5b4127191802d 100644 --- a/packages/kbn-monaco/src/console/index.ts +++ b/packages/kbn-monaco/src/console/index.ts @@ -20,14 +20,9 @@ import { consoleOutputLanguageConfiguration, } from './lexer_rules'; -export { - CONSOLE_LANG_ID, - CONSOLE_OUTPUT_LANG_ID, - CONSOLE_THEME_ID, - CONSOLE_OUTPUT_THEME_ID, -} from './constants'; +export { CONSOLE_LANG_ID, CONSOLE_OUTPUT_LANG_ID, CONSOLE_THEME_ID } from './constants'; -export { buildConsoleTheme, buildConsoleOutputTheme } from './theme'; +export { buildConsoleTheme } from './theme'; export const ConsoleLang: LangModuleType = { ID: CONSOLE_LANG_ID, diff --git a/packages/kbn-monaco/src/console/theme.ts b/packages/kbn-monaco/src/console/theme.ts new file mode 100644 index 0000000000000..66e2bfab812bd --- /dev/null +++ b/packages/kbn-monaco/src/console/theme.ts @@ -0,0 +1,44 @@ +/* + * 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 { makeHighContrastColor } from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { darkMode } from '@kbn/ui-theme'; +import { buildLightTheme, buildDarkTheme } from '../code_editor'; +import { themeRuleGroupBuilderFactory } from '../common/theme'; +import { monaco } from '../monaco_imports'; + +const buildRuleGroup = themeRuleGroupBuilderFactory(); + +const background = euiThemeVars.euiFormBackgroundColor; +const booleanTextColor = '#585CF6'; +const methodTextColor = '#DD0A73'; +const urlTextColor = '#00A69B'; +export const buildConsoleTheme = (): monaco.editor.IStandaloneThemeData => { + const euiTheme = darkMode ? buildDarkTheme() : buildLightTheme(); + return { + ...euiTheme, + rules: [ + ...euiTheme.rules, + ...buildRuleGroup( + ['string-literal', 'multi-string', 'punctuation.end-triple-quote'], + makeHighContrastColor(euiThemeVars.euiColorDangerText)(background) + ), + ...buildRuleGroup( + ['constant.language.boolean'], + makeHighContrastColor(booleanTextColor)(background) + ), + ...buildRuleGroup( + ['constant.numeric'], + makeHighContrastColor(euiThemeVars.euiColorAccentText)(background) + ), + ...buildRuleGroup(['method'], makeHighContrastColor(methodTextColor)(background)), + ...buildRuleGroup(['url'], makeHighContrastColor(urlTextColor)(background)), + ], + }; +}; diff --git a/packages/kbn-monaco/src/console/theme/editor_theme.ts b/packages/kbn-monaco/src/console/theme/editor_theme.ts deleted file mode 100644 index f01c34919bb09..0000000000000 --- a/packages/kbn-monaco/src/console/theme/editor_theme.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { makeHighContrastColor } from '@elastic/eui'; -import { euiThemeVars } from '@kbn/ui-theme'; - -import { themeRuleGroupBuilderFactory } from '../../common/theme'; -import { monaco } from '../../monaco_imports'; -import { buildConsoleSharedTheme } from './shared'; - -const buildRuleGroup = themeRuleGroupBuilderFactory(); - -const background = euiThemeVars.euiColorLightestShade; -const methodTextColor = '#DD0A73'; -const urlTextColor = '#00A69B'; -export const buildConsoleTheme = (): monaco.editor.IStandaloneThemeData => { - const sharedTheme = buildConsoleSharedTheme(); - return { - ...sharedTheme, - rules: [ - ...sharedTheme.rules, - ...buildRuleGroup(['method'], makeHighContrastColor(methodTextColor)(background)), - ...buildRuleGroup(['url'], makeHighContrastColor(urlTextColor)(background)), - ], - }; -}; diff --git a/packages/kbn-monaco/src/console/theme/index.ts b/packages/kbn-monaco/src/console/theme/index.ts deleted file mode 100644 index b9e03585f6297..0000000000000 --- a/packages/kbn-monaco/src/console/theme/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { buildConsoleTheme } from './editor_theme'; -export { buildConsoleOutputTheme } from './output_theme'; diff --git a/packages/kbn-monaco/src/console/theme/output_theme.ts b/packages/kbn-monaco/src/console/theme/output_theme.ts deleted file mode 100644 index ad6ffae757128..0000000000000 --- a/packages/kbn-monaco/src/console/theme/output_theme.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { monaco } from '../../monaco_imports'; -import { buildConsoleSharedTheme } from './shared'; - -export const buildConsoleOutputTheme = (): monaco.editor.IStandaloneThemeData => { - const sharedTheme = buildConsoleSharedTheme(); - return { - ...sharedTheme, - }; -}; diff --git a/packages/kbn-monaco/src/console/theme/shared.ts b/packages/kbn-monaco/src/console/theme/shared.ts deleted file mode 100644 index 3bdb543f6ef9d..0000000000000 --- a/packages/kbn-monaco/src/console/theme/shared.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { makeHighContrastColor } from '@elastic/eui'; -import { darkMode, euiThemeVars } from '@kbn/ui-theme'; - -import { themeRuleGroupBuilderFactory } from '../../common/theme'; -import { monaco } from '../../monaco_imports'; - -const buildRuleGroup = themeRuleGroupBuilderFactory(); - -const background = euiThemeVars.euiColorLightestShade; -const stringTextColor = '#009926'; -const commentTextColor = '#4C886B'; -const variableTextColor = '#0079A5'; -const booleanTextColor = '#585CF6'; -const numericTextColor = variableTextColor; -export const buildConsoleSharedTheme = (): monaco.editor.IStandaloneThemeData => { - return { - base: darkMode ? 'vs-dark' : 'vs', - inherit: true, - rules: [ - ...buildRuleGroup( - ['string', 'string-literal', 'multi-string', 'punctuation.end-triple-quote'], - makeHighContrastColor(stringTextColor)(background) - ), - ...buildRuleGroup(['comment'], makeHighContrastColor(commentTextColor)(background)), - ...buildRuleGroup(['variable'], makeHighContrastColor(variableTextColor)(background)), - ...buildRuleGroup( - ['constant.language.boolean'], - makeHighContrastColor(booleanTextColor)(background) - ), - ...buildRuleGroup(['constant.numeric'], makeHighContrastColor(numericTextColor)(background)), - ], - colors: { - 'editor.background': background, - // color of the line numbers - 'editorLineNumber.foreground': euiThemeVars.euiColorDarkShade, - // color of the active line number - 'editorLineNumber.activeForeground': euiThemeVars.euiColorDarkShade, - // background of the line numbers side panel - 'editorGutter.background': euiThemeVars.euiColorEmptyShade, - }, - }; -}; diff --git a/packages/kbn-monaco/src/register_globals.ts b/packages/kbn-monaco/src/register_globals.ts index 7e12ee24b386a..0b1bcd44f2554 100644 --- a/packages/kbn-monaco/src/register_globals.ts +++ b/packages/kbn-monaco/src/register_globals.ts @@ -13,14 +13,7 @@ import { monaco } from './monaco_imports'; import { ESQL_THEME_ID, ESQLLang, buildESQlTheme } from './esql'; import { YAML_LANG_ID } from './yaml'; import { registerLanguage, registerTheme } from './helpers'; -import { - ConsoleLang, - ConsoleOutputLang, - CONSOLE_THEME_ID, - CONSOLE_OUTPUT_THEME_ID, - buildConsoleTheme, - buildConsoleOutputTheme, -} from './console'; +import { ConsoleLang, ConsoleOutputLang, CONSOLE_THEME_ID, buildConsoleTheme } from './console'; import { CODE_EDITOR_LIGHT_THEME_ID, CODE_EDITOR_DARK_THEME_ID, @@ -58,7 +51,6 @@ registerLanguage(ConsoleOutputLang); */ registerTheme(ESQL_THEME_ID, buildESQlTheme()); registerTheme(CONSOLE_THEME_ID, buildConsoleTheme()); -registerTheme(CONSOLE_OUTPUT_THEME_ID, buildConsoleOutputTheme()); registerTheme(CODE_EDITOR_LIGHT_THEME_ID, buildLightTheme()); registerTheme(CODE_EDITOR_DARK_THEME_ID, buildDarkTheme()); registerTheme(CODE_EDITOR_LIGHT_THEME_TRANSPARENT_ID, buildLightTransparentTheme()); diff --git a/packages/kbn-monaco/tsconfig.json b/packages/kbn-monaco/tsconfig.json index 4df3aa9b486b3..d39ed146027a9 100644 --- a/packages/kbn-monaco/tsconfig.json +++ b/packages/kbn-monaco/tsconfig.json @@ -26,7 +26,7 @@ "@kbn/repo-info", "@kbn/ui-theme", "@kbn/esql-ast", - "@kbn/esql-validation-autocomplete" + "@kbn/esql-validation-autocomplete", ], "exclude": [ "target/**/*", diff --git a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx b/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx index a5647cb1c49f1..f11ea7479d461 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx @@ -13,7 +13,7 @@ import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import { i18n } from '@kbn/i18n'; import { EuiScreenReaderOnly } from '@elastic/eui'; -import { CONSOLE_OUTPUT_THEME_ID, CONSOLE_OUTPUT_LANG_ID, monaco } from '@kbn/monaco'; +import { CONSOLE_THEME_ID, CONSOLE_OUTPUT_LANG_ID, monaco } from '@kbn/monaco'; import { useEditorReadContext, useRequestReadContext } from '../../../contexts'; import { convertMapboxVectorTileToJson } from '../legacy/console_editor/mapbox_vector_tile'; import { @@ -99,9 +99,10 @@ export const MonacoEditorOutput: FunctionComponent = () => { editorDidMount={editorDidMountCallback} editorWillUnmount={editorWillUnmountCallback} options={{ + readOnly: true, fontSize: readOnlySettings.fontSize, wordWrap: readOnlySettings.wrapMode === true ? 'on' : 'off', - theme: mode === CONSOLE_OUTPUT_LANG_ID ? CONSOLE_OUTPUT_THEME_ID : undefined, + theme: CONSOLE_THEME_ID, automaticLayout: true, }} /> diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 37f2753b1a99b..a4a7469a69bfe 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -100,6 +100,7 @@ @include kbnResizer; // Give the aria selection border priority when the divider is selected on IE11 and Chrome z-index: $euiZLevel1; + background-color: $euiColorLightestShade; } // SASSTODO: This component seems to not be used anymore? From 06d32af345ce56b3345afced38991bc1e1a53369 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 30 Apr 2024 10:26:30 -0400 Subject: [PATCH 045/104] feat(slo): health status (#181351) --- .../src/rest_specs/routes/get_slo_health.ts | 35 ++ .../src/rest_specs/routes/index.ts | 1 + .../kbn-slo-schema/src/schema/health.ts | 18 + .../kbn-slo-schema/src/schema/index.ts | 1 + .../slo/public/hooks/query_key_factory.ts | 2 + .../slo/public/hooks/use_fetch_slo_health.ts | 57 +++ .../slo_details/components/slo_details.tsx | 2 + .../components/slo_health_callout.tsx | 113 ++++++ .../health_callout/health_callout.tsx | 167 +++++++++ .../public/pages/slos/components/slo_list.tsx | 9 +- .../pages/slos/components/slos_view.tsx | 36 +- .../slo/server/domain/models/health.ts | 14 + .../slo/server/routes/slo/route.ts | 25 +- .../__snapshots__/create_slo.test.ts.snap | 2 + .../__snapshots__/reset_slo.test.ts.snap | 2 + .../summary_search_client.test.ts.snap | 50 +-- .../fixtures/summary_search_document.ts | 54 +-- .../server/services/get_slo_health.test.ts | 349 ++++++++++++++++++ .../slo/server/services/get_slo_health.ts | 171 +++++++++ .../slo/server/services/index.ts | 1 + .../services/summary_search_client.test.ts | 29 +- .../helpers/create_temp_summary.ts | 4 + .../remote_summary_doc_to_slo.test.ts | 4 + 23 files changed, 1049 insertions(+), 97 deletions(-) create mode 100644 x-pack/packages/kbn-slo-schema/src/rest_specs/routes/get_slo_health.ts create mode 100644 x-pack/packages/kbn-slo-schema/src/schema/health.ts create mode 100644 x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slo_health.ts create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_health_callout.tsx create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slos/components/health_callout/health_callout.tsx create mode 100644 x-pack/plugins/observability_solution/slo/server/domain/models/health.ts create mode 100644 x-pack/plugins/observability_solution/slo/server/services/get_slo_health.test.ts create mode 100644 x-pack/plugins/observability_solution/slo/server/services/get_slo_health.ts diff --git a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/get_slo_health.ts b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/get_slo_health.ts new file mode 100644 index 0000000000000..7865282cf55ec --- /dev/null +++ b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/get_slo_health.ts @@ -0,0 +1,35 @@ +/* + * 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 * as t from 'io-ts'; +import { healthStatusSchema, sloIdSchema, stateSchema } from '../../schema'; +import { allOrAnyString } from '../../schema/common'; + +const fetchSLOHealthResponseSchema = t.array( + t.type({ + sloId: sloIdSchema, + sloInstanceId: allOrAnyString, + sloRevision: t.number, + state: stateSchema, + health: t.type({ + overall: healthStatusSchema, + rollup: healthStatusSchema, + summary: healthStatusSchema, + }), + }) +); + +const fetchSLOHealthParamsSchema = t.type({ + body: t.type({ + list: t.array(t.type({ sloId: sloIdSchema, sloInstanceId: allOrAnyString })), + }), +}); + +type FetchSLOHealthResponse = t.OutputOf; +type FetchSLOHealthParams = t.TypeOf; + +export { fetchSLOHealthParamsSchema, fetchSLOHealthResponseSchema }; +export type { FetchSLOHealthResponse, FetchSLOHealthParams }; diff --git a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/index.ts b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/index.ts index 57058d03790bb..93c06929dff29 100644 --- a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/index.ts +++ b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/index.ts @@ -21,3 +21,4 @@ export * from './delete_instance'; export * from './fetch_historical_summary'; export * from './put_settings'; export * from './get_suggestions'; +export * from './get_slo_health'; diff --git a/x-pack/packages/kbn-slo-schema/src/schema/health.ts b/x-pack/packages/kbn-slo-schema/src/schema/health.ts new file mode 100644 index 0000000000000..02a2b28dcbd7f --- /dev/null +++ b/x-pack/packages/kbn-slo-schema/src/schema/health.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 * as t from 'io-ts'; + +const healthStatusSchema = t.union([t.literal('healthy'), t.literal('unhealthy')]); +const stateSchema = t.union([ + t.literal('no_data'), + t.literal('indexing'), + t.literal('running'), + t.literal('stale'), +]); + +export { healthStatusSchema, stateSchema }; diff --git a/x-pack/packages/kbn-slo-schema/src/schema/index.ts b/x-pack/packages/kbn-slo-schema/src/schema/index.ts index 5fdaa72f71527..ac1adce34f67f 100644 --- a/x-pack/packages/kbn-slo-schema/src/schema/index.ts +++ b/x-pack/packages/kbn-slo-schema/src/schema/index.ts @@ -11,3 +11,4 @@ export * from './indicators'; export * from './time_window'; export * from './slo'; export * from './settings'; +export * from './health'; diff --git a/x-pack/plugins/observability_solution/slo/public/hooks/query_key_factory.ts b/x-pack/plugins/observability_solution/slo/public/hooks/query_key_factory.ts index 09cd8400b07ea..dd8f3c49a4b43 100644 --- a/x-pack/plugins/observability_solution/slo/public/hooks/query_key_factory.ts +++ b/x-pack/plugins/observability_solution/slo/public/hooks/query_key_factory.ts @@ -46,6 +46,8 @@ export const sloKeys = { definitions: (search: string, page: number, perPage: number, includeOutdatedOnly: boolean) => [...sloKeys.all, 'definitions', search, page, perPage, includeOutdatedOnly] as const, globalDiagnosis: () => [...sloKeys.all, 'globalDiagnosis'] as const, + health: (list: Array<{ sloId: string; sloInstanceId: string }>) => + [...sloKeys.all, 'health', list] as const, burnRates: ( sloId: string, instanceId: string | undefined, diff --git a/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slo_health.ts b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slo_health.ts new file mode 100644 index 0000000000000..4d8439331d042 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slo_health.ts @@ -0,0 +1,57 @@ +/* + * 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 { ALL_VALUE, FetchSLOHealthResponse, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { useQuery } from '@tanstack/react-query'; +import { useKibana } from '../utils/kibana_react'; +import { sloKeys } from './query_key_factory'; + +export interface UseFetchSloHealth { + data: FetchSLOHealthResponse | undefined; + isLoading: boolean; + isError: boolean; +} + +export interface Params { + list: SLOWithSummaryResponse[]; +} + +export function useFetchSloHealth({ list }: Params): UseFetchSloHealth { + const { http } = useKibana().services; + const payload = list.map((slo) => ({ + sloId: slo.id, + sloInstanceId: slo.instanceId ?? ALL_VALUE, + })); + + const { isLoading, isError, data } = useQuery({ + queryKey: sloKeys.health(payload), + queryFn: async ({ signal }) => { + try { + const response = await http.post( + '/internal/observability/slos/_health', + { + body: JSON.stringify({ list: payload }), + signal, + } + ); + + return response; + } catch (error) { + // ignore error + } + }, + enabled: Boolean(list.length > 0), + refetchOnWindowFocus: false, + keepPreviousData: true, + }); + + return { + data, + isLoading, + isError, + }; +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx index 7a2be1bfb394e..01d62098e8802 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx @@ -18,6 +18,7 @@ import { EventsChartPanel } from './events_chart_panel'; import { Overview } from './overview/overview'; import { SliChartPanel } from './sli_chart_panel'; import { SloDetailsAlerts } from './slo_detail_alerts'; +import { SloHealthCallout } from './slo_health_callout'; import { SloRemoteCallout } from './slo_remote_callout'; export const TAB_ID_URL_PARAM = 'tabId'; @@ -126,6 +127,7 @@ export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) { return selectedTabId === OVERVIEW_TAB_ID ? ( + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_health_callout.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_health_callout.tsx new file mode 100644 index 0000000000000..0b9e312910319 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_health_callout.tsx @@ -0,0 +1,113 @@ +/* + * 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 { + EuiButton, + EuiButtonIcon, + EuiCallOut, + EuiCopy, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import React from 'react'; +import { getSLOSummaryTransformId, getSLOTransformId } from '../../../../common/constants'; +import { useFetchSloHealth } from '../../../hooks/use_fetch_slo_health'; +import { useKibana } from '../../../utils/kibana_react'; + +export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) { + const { http } = useKibana().services; + const { isLoading, isError, data } = useFetchSloHealth({ list: [slo] }); + + if (isLoading || isError || data === undefined || data?.length !== 1) { + return null; + } + + const health = data[0].health; + if (health.overall === 'healthy') { + return null; + } + + const count = health.rollup === 'unhealthy' && health.summary === 'unhealthy' ? 2 : 1; + + return ( + + + + +
      + {health.rollup === 'unhealthy' && ( +
    • + {getSLOTransformId(slo.id, slo.revision)} + + {(copy) => ( + + )} + +
    • + )} + {health.summary === 'unhealthy' && ( +
    • + {getSLOSummaryTransformId(slo.id, slo.revision)} + + {(copy) => ( + + )} + +
    • + )} +
    +
    + + + + + + +
    +
    + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/health_callout/health_callout.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/health_callout/health_callout.tsx new file mode 100644 index 0000000000000..ce956b00a8170 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/health_callout/health_callout.tsx @@ -0,0 +1,167 @@ +/* + * 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 { + EuiButton, + EuiButtonEmpty, + EuiButtonIcon, + EuiCallOut, + EuiCopy, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import React, { useState } from 'react'; +import { getSLOSummaryTransformId, getSLOTransformId } from '../../../../../common/constants'; +import { useFetchSloHealth } from '../../../../hooks/use_fetch_slo_health'; +import { useKibana } from '../../../../utils/kibana_react'; + +const CALLOUT_SESSION_STORAGE_KEY = 'slo_health_callout_hidden'; + +export function HealthCallout({ sloList }: { sloList: SLOWithSummaryResponse[] }) { + const { http } = useKibana().services; + const { isLoading, isError, data: results } = useFetchSloHealth({ list: sloList }); + const [showCallOut, setShowCallOut] = useState( + !sessionStorage.getItem(CALLOUT_SESSION_STORAGE_KEY) + ); + const [isOpen, setIsOpen] = useState(false); + + if (!showCallOut) { + return null; + } + + if (isLoading || isError || results === undefined || results?.length === 0) { + return null; + } + + const unhealthySloList = results.filter((result) => result.health.overall === 'unhealthy'); + if (unhealthySloList.length === 0) { + return null; + } + + const unhealthyRollupTransforms = results.filter( + (result) => result.health.rollup === 'unhealthy' + ); + const unhealthySummaryTransforms = results.filter( + (result) => result.health.summary === 'unhealthy' + ); + + const dismiss = () => { + setShowCallOut(false); + sessionStorage.setItem('slo_health_callout_hidden', 'true'); + }; + + return ( + { + setIsOpen(!isOpen); + }} + title={ + + } + > + {isOpen && ( + { + e.stopPropagation(); + }} + > + + +
      + {unhealthyRollupTransforms.map((result) => ( +
    • + {getSLOTransformId(result.sloId, result.sloRevision)} + + {(copy) => ( + + )} + +
    • + ))} + + {unhealthySummaryTransforms.map((result) => ( +
    • + {getSLOSummaryTransformId(result.sloId, result.sloRevision)} + + {(copy) => ( + + )} + +
    • + ))} +
    +
    + + + + + + + + + + + + +
    + )} +
    + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slo_list.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slo_list.tsx index 64ebfe7a6a2d8..be10b99ae5531 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slo_list.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slo_list.tsx @@ -7,17 +7,18 @@ import { EuiFlexGroup, EuiFlexItem, EuiTablePagination } from '@elastic/eui'; import { useIsMutating } from '@tanstack/react-query'; -import React, { useEffect } from 'react'; import dedent from 'dedent'; import { groupBy as _groupBy, mapValues } from 'lodash'; -import { useKibana } from '../../../utils/kibana_react'; +import React, { useEffect } from 'react'; import { useFetchSloList } from '../../../hooks/use_fetch_slo_list'; +import { useKibana } from '../../../utils/kibana_react'; import { useUrlSearchState } from '../hooks/use_url_search_state'; +import { GroupView } from './grouped_slos/group_view'; import { SlosView } from './slos_view'; import { ToggleSLOView } from './toggle_slo_view'; -import { GroupView } from './grouped_slos/group_view'; export function SloList() { + const { observabilityAIAssistant } = useKibana().services; const { state, onStateChange } = useUrlSearchState(); const { view, page, perPage, kqlQuery, filters, tagsFilter, statusFilter, groupBy } = state; @@ -37,8 +38,6 @@ export function SloList() { sortDirection: state.sort.direction, lastRefresh: state.lastRefresh, }); - - const { observabilityAIAssistant } = useKibana().services; const { results = [], total = 0 } = sloList ?? {}; const isDeletingSlo = Boolean(useIsMutating(['deleteSlo'])); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slos_view.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slos_view.tsx index e317d33290cb2..3199627a71e66 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slos_view.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/slos_view.tsx @@ -5,11 +5,12 @@ * 2.0. */ -import { EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import React from 'react'; import { SloListCardView } from './card_view/slos_card_view'; import { SloListCompactView } from './compact_view/slo_list_compact_view'; +import { HealthCallout } from './health_callout/health_callout'; import { SloListEmpty } from './slo_list_empty'; import { SloListError } from './slo_list_error'; import { SloListView } from './slo_list_view/slo_list_view'; @@ -33,23 +34,38 @@ export function SlosView({ sloList, loading, error, sloView }: Props) { if (sloView === 'cardView') { return ( - - - + + + + + + + + ); } if (sloView === 'compactView') { return ( - - - + + + + + + + + ); } return ( - - - + + + + + + + + ); } diff --git a/x-pack/plugins/observability_solution/slo/server/domain/models/health.ts b/x-pack/plugins/observability_solution/slo/server/domain/models/health.ts new file mode 100644 index 0000000000000..7d4e6dd6c9c71 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/server/domain/models/health.ts @@ -0,0 +1,14 @@ +/* + * 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 { healthStatusSchema, stateSchema } from '@kbn/slo-schema'; +import * as t from 'io-ts'; + +type HealthStatus = t.OutputOf; +type State = t.OutputOf; + +export type { HealthStatus, State }; diff --git a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts index 80a9a18542da9..390967c62ecd0 100644 --- a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts +++ b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts @@ -17,6 +17,7 @@ import { findSLOParamsSchema, getPreviewDataParamsSchema, getSLOBurnRatesParamsSchema, + fetchSLOHealthParamsSchema, getSLOInstancesParamsSchema, getSLOParamsSchema, manageSLOParamsSchema, @@ -24,7 +25,6 @@ import { resetSLOParamsSchema, updateSLOParamsSchema, } from '@kbn/slo-schema'; -import { GetSLOSuggestions } from '../../services/get_slo_suggestions'; import type { IndicatorTypes } from '../../domain/models'; import { CreateSLO, @@ -36,6 +36,7 @@ import { FindSLO, FindSLOGroups, GetSLO, + GetSLOHealth, KibanaSavedObjectsSLORepository, UpdateSLO, } from '../../services'; @@ -45,6 +46,7 @@ import { getBurnRates } from '../../services/get_burn_rates'; import { getGlobalDiagnosis } from '../../services/get_diagnosis'; import { GetPreviewData } from '../../services/get_preview_data'; import { GetSLOInstances } from '../../services/get_slo_instances'; +import { GetSLOSuggestions } from '../../services/get_slo_suggestions'; import { DefaultHistoricalSummaryClient } from '../../services/historical_summary_client'; import { ManageSLO } from '../../services/manage_slo'; import { ResetSLO } from '../../services/reset_slo'; @@ -558,6 +560,26 @@ const getDiagnosisRoute = createSloServerRoute({ }, }); +const fetchSloHealthRoute = createSloServerRoute({ + endpoint: 'POST /internal/observability/slos/_health', + options: { + tags: ['access:slo_read'], + access: 'internal', + }, + params: fetchSLOHealthParamsSchema, + handler: async ({ context, params, logger }) => { + await assertPlatinumLicense(context); + + const soClient = (await context.core).savedObjects.client; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const repository = new KibanaSavedObjectsSLORepository(soClient, logger); + + const getSLOHealth = new GetSLOHealth(esClient, repository); + + return await getSLOHealth.execute(params.body); + }, +}); + const getSloBurnRates = createSloServerRoute({ endpoint: 'POST /internal/observability/slos/{id}/_burn_rates', options: { @@ -639,6 +661,7 @@ const putSloSettings = createSloServerRoute({ }); export const sloRouteRepository = { + ...fetchSloHealthRoute, ...getSloSettingsRoute, ...putSloSettings, ...createSLORoute, diff --git a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/create_slo.test.ts.snap b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/create_slo.test.ts.snap index 4f9bd9ab4d8d4..a8bf14900b2cf 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/create_slo.test.ts.snap +++ b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/create_slo.test.ts.snap @@ -182,6 +182,7 @@ Array [ "goodEvents": 0, "isTempDoc": true, "kibanaUrl": "http://myhost.com/mock-server-basepath", + "latestSliTimestamp": null, "service": Object { "environment": "irrelevant", "name": "irrelevant", @@ -222,6 +223,7 @@ Array [ "spaceId": "some-space", "status": "NO_DATA", "statusCode": 0, + "summaryUpdatedAt": null, "totalEvents": 0, "transaction": Object { "name": "irrelevant", diff --git a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/reset_slo.test.ts.snap b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/reset_slo.test.ts.snap index d3cefbd8cc4d4..edf23b4e5e716 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/reset_slo.test.ts.snap +++ b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/reset_slo.test.ts.snap @@ -469,6 +469,7 @@ exports[`ResetSLO resets all associated resources 11`] = ` "goodEvents": 0, "isTempDoc": true, "kibanaUrl": "http://myhost.com/mock-server-basepath", + "latestSliTimestamp": null, "service": Object { "environment": "irrelevant", "name": "irrelevant", @@ -513,6 +514,7 @@ exports[`ResetSLO resets all associated resources 11`] = ` "spaceId": "some-space", "status": "NO_DATA", "statusCode": 0, + "summaryUpdatedAt": null, "totalEvents": 0, "transaction": Object { "name": "irrelevant", diff --git a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/summary_search_client.test.ts.snap b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/summary_search_client.test.ts.snap index c5598500e65c3..fc76eaeb65c38 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/summary_search_client.test.ts.snap +++ b/x-pack/plugins/observability_solution/slo/server/services/__snapshots__/summary_search_client.test.ts.snap @@ -41,13 +41,13 @@ Object { "sloId": "slo-one", "summary": Object { "errorBudget": Object { - "consumed": 0.4, - "initial": 0.02, + "consumed": 0, + "initial": 0.001, "isEstimated": false, - "remaining": 0.6, + "remaining": 1, }, - "sliValue": 0.9, - "status": "HEALTHY", + "sliValue": -1, + "status": "NO_DATA", }, }, Object { @@ -56,13 +56,13 @@ Object { "sloId": "slo_two", "summary": Object { "errorBudget": Object { - "consumed": 0.4, - "initial": 0.02, + "consumed": 0, + "initial": 0.001, "isEstimated": false, - "remaining": 0.6, + "remaining": 1, }, - "sliValue": 0.9, - "status": "HEALTHY", + "sliValue": -1, + "status": "NO_DATA", }, }, Object { @@ -71,13 +71,13 @@ Object { "sloId": "slo-three", "summary": Object { "errorBudget": Object { - "consumed": 0.4, - "initial": 0.02, + "consumed": 0, + "initial": 0.001, "isEstimated": false, - "remaining": 0.6, + "remaining": 1, }, - "sliValue": 0.9, - "status": "HEALTHY", + "sliValue": -1, + "status": "NO_DATA", }, }, Object { @@ -86,13 +86,13 @@ Object { "sloId": "slo-five", "summary": Object { "errorBudget": Object { - "consumed": 0.4, - "initial": 0.02, + "consumed": 0, + "initial": 0.001, "isEstimated": false, - "remaining": 0.6, + "remaining": 1, }, - "sliValue": 0.9, - "status": "HEALTHY", + "sliValue": -1, + "status": "NO_DATA", }, }, Object { @@ -101,13 +101,13 @@ Object { "sloId": "slo-four", "summary": Object { "errorBudget": Object { - "consumed": 0.4, - "initial": 0.02, + "consumed": 0, + "initial": 0.001, "isEstimated": false, - "remaining": 0.6, + "remaining": 1, }, - "sliValue": 0.9, - "status": "HEALTHY", + "sliValue": -1, + "status": "NO_DATA", }, }, ], diff --git a/x-pack/plugins/observability_solution/slo/server/services/fixtures/summary_search_document.ts b/x-pack/plugins/observability_solution/slo/server/services/fixtures/summary_search_document.ts index 17b45656aa525..8837e567c97cc 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/fixtures/summary_search_document.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/fixtures/summary_search_document.ts @@ -5,51 +5,21 @@ * 2.0. */ -import { ALL_VALUE } from '@kbn/slo-schema'; +import { IBasePath } from '@kbn/core/server'; import { v4 as uuidv4 } from 'uuid'; +import { SLODefinition } from '../../domain/models'; +import { + createTempSummaryDocument, + EsSummaryDocument, +} from '../summary_transform_generator/helpers/create_temp_summary'; -export const aSummaryDocument = ({ - id = uuidv4(), - sliValue = 0.9, - consumed = 0.4, - isTempDoc = false, - status = 'HEALTHY', -} = {}) => { +export const aSummaryDocument = ( + slo: SLODefinition, + params: Partial = {} +): EsSummaryDocument => { return { - goodEvents: 96, - totalEvents: 100, - errorBudgetEstimated: false, - errorBudgetRemaining: 1 - consumed, - errorBudgetConsumed: consumed, - isTempDoc, - service: { - environment: null, - name: null, - }, - slo: { - indicator: { - type: 'sli.kql.custom', - }, - timeWindow: { - duration: '30d', - type: 'rolling', - }, - instanceId: ALL_VALUE, - name: 'irrelevant', - description: '', - id, - budgetingMethod: 'occurrences', - revision: 1, - tags: ['tag-one', 'tag-two', 'irrelevant'], - }, - errorBudgetInitial: 0.02, - transaction: { - name: null, - type: null, - }, - sliValue, - statusCode: 4, - status, + ...createTempSummaryDocument(slo, 'default', { publicBaseUrl: '' } as IBasePath), + ...params, }; }; diff --git a/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.test.ts b/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.test.ts new file mode 100644 index 0000000000000..ce1522de40ada --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.test.ts @@ -0,0 +1,349 @@ +/* + * 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 { ElasticsearchClient } from '@kbn/core/server'; +import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { ALL_VALUE } from '@kbn/slo-schema'; +import { getSLOSummaryTransformId, getSLOTransformId } from '../../common/constants'; +import { createSLO } from './fixtures/slo'; +import { + aHitFromSummaryIndex, + aHitFromTempSummaryIndex, + aSummaryDocument, +} from './fixtures/summary_search_document'; +import { GetSLOHealth } from './get_slo_health'; +import { createSLORepositoryMock } from './mocks'; +import { SLORepository } from './slo_repository'; + +describe('GetSLOHealth', () => { + let mockRepository: jest.Mocked; + let mockEsClient: jest.Mocked; + let getSLOHealth: GetSLOHealth; + + beforeEach(() => { + mockRepository = createSLORepositoryMock(); + mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + getSLOHealth = new GetSLOHealth(mockEsClient, mockRepository); + }); + + it('returns the health and state', async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [ + aHitFromSummaryIndex(aSummaryDocument(slo)), + aHitFromTempSummaryIndex(aSummaryDocument(slo, { isTempDoc: true })), // kept + ], + }, + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "health": Object { + "overall": "unhealthy", + "rollup": "unhealthy", + "summary": "unhealthy", + }, + "sloId": "95ffb9af-1384-4d24-8e3f-345a03d7a439", + "sloInstanceId": "*", + "sloRevision": 1, + "state": "no_data", + }, + ] + `); + }); + + it('handles inexistant sloId', async () => { + mockRepository.findAllByIds.mockResolvedValueOnce([]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 0, + relation: 'eq', + }, + max_score: 1, + hits: [], + }, + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: 'inexistant', sloInstanceId: ALL_VALUE }], + }); + + expect(result).toHaveLength(0); + }); + + describe('computes health', () => { + it('returns healthy when both transforms are healthy', async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [aHitFromSummaryIndex(aSummaryDocument(slo))], + }, + }); + + // @ts-ignore + mockEsClient.transform.getTransformStats.mockResolvedValue({ + transforms: [ + { id: getSLOTransformId(slo.id, slo.revision), health: { status: 'green' } }, + { id: getSLOSummaryTransformId(slo.id, slo.revision), health: { status: 'green' } }, + ], + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "health": Object { + "overall": "healthy", + "rollup": "healthy", + "summary": "healthy", + }, + "sloId": "95ffb9af-1384-4d24-8e3f-345a03d7a439", + "sloInstanceId": "*", + "sloRevision": 1, + "state": "no_data", + }, + ] + `); + }); + + it('returns unhealthy whenever one of the transform is unhealthy', async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [aHitFromSummaryIndex(aSummaryDocument(slo))], + }, + }); + + // @ts-ignore + mockEsClient.transform.getTransformStats.mockResolvedValue({ + transforms: [ + { id: getSLOTransformId(slo.id, slo.revision), health: { status: 'yellow' } }, + { id: getSLOSummaryTransformId(slo.id, slo.revision), health: { status: 'green' } }, + ], + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "health": Object { + "overall": "unhealthy", + "rollup": "unhealthy", + "summary": "healthy", + }, + "sloId": "95ffb9af-1384-4d24-8e3f-345a03d7a439", + "sloInstanceId": "*", + "sloRevision": 1, + "state": "no_data", + }, + ] + `); + }); + }); + + describe('computes state', () => { + it('returns stale when summaryUpdatedAt is 2 days old', async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [ + aHitFromSummaryIndex( + aSummaryDocument(slo, { + summaryUpdatedAt: new Date(Date.now() - 49 * 60 * 60 * 1000).toISOString(), + latestSliTimestamp: new Date(Date.now() - 60 * 60 * 60 * 1000).toISOString(), + isTempDoc: false, + }) + ), + ], + }, + }); + + // @ts-ignore + mockEsClient.transform.getTransformStats.mockResolvedValue({ + transforms: [ + { id: getSLOTransformId(slo.id, slo.revision), health: { status: 'green' } }, + { id: getSLOSummaryTransformId(slo.id, slo.revision), health: { status: 'green' } }, + ], + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result[0].state).toBe('stale'); + }); + + it("returns 'indexing' when diff(summaryUpdatedAt - latestSliTimestamp) >= 10min", async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + const now = Date.now(); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [ + aHitFromSummaryIndex( + aSummaryDocument(slo, { + summaryUpdatedAt: new Date(now).toISOString(), + latestSliTimestamp: new Date(now - 10 * 60 * 1000).toISOString(), // 10min + isTempDoc: false, + }) + ), + ], + }, + }); + + // @ts-ignore + mockEsClient.transform.getTransformStats.mockResolvedValue({ + transforms: [ + { id: getSLOTransformId(slo.id, slo.revision), health: { status: 'green' } }, + { id: getSLOSummaryTransformId(slo.id, slo.revision), health: { status: 'green' } }, + ], + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result[0].state).toBe('indexing'); + }); + + it("returns 'running' when diff(summaryUpdatedAt - latestSliTimestamp) < 10min", async () => { + const slo = createSLO({ id: '95ffb9af-1384-4d24-8e3f-345a03d7a439' }); + const now = Date.now(); + mockRepository.findAllByIds.mockResolvedValueOnce([slo]); + mockEsClient.search.mockResolvedValue({ + took: 0, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 1, + relation: 'eq', + }, + max_score: 1, + hits: [ + aHitFromSummaryIndex( + aSummaryDocument(slo, { + summaryUpdatedAt: new Date(now).toISOString(), + latestSliTimestamp: new Date(now - 9 * 60 * 1000 + 59 * 1000).toISOString(), // 9min59s + isTempDoc: false, + }) + ), + ], + }, + }); + + // @ts-ignore + mockEsClient.transform.getTransformStats.mockResolvedValue({ + transforms: [ + { id: getSLOTransformId(slo.id, slo.revision), health: { status: 'green' } }, + { id: getSLOSummaryTransformId(slo.id, slo.revision), health: { status: 'green' } }, + ], + }); + + const result = await getSLOHealth.execute({ + list: [{ sloId: slo.id, sloInstanceId: ALL_VALUE }], + }); + + expect(result[0].state).toBe('running'); + }); + }); +}); diff --git a/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.ts b/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.ts new file mode 100644 index 0000000000000..76493e8a7f4e4 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/server/services/get_slo_health.ts @@ -0,0 +1,171 @@ +/* + * 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 { TransformGetTransformStatsTransformStats } from '@elastic/elasticsearch/lib/api/types'; +import { ElasticsearchClient } from '@kbn/core/server'; +import { + FetchSLOHealthParams, + FetchSLOHealthResponse, + fetchSLOHealthResponseSchema, +} from '@kbn/slo-schema'; +import { Dictionary, groupBy, keyBy } from 'lodash'; +import moment from 'moment'; +import { + getSLOSummaryTransformId, + getSLOTransformId, + SLO_SUMMARY_DESTINATION_INDEX_PATTERN, +} from '../../common/constants'; +import { SLODefinition } from '../domain/models'; +import { HealthStatus, State } from '../domain/models/health'; +import { SLORepository } from './slo_repository'; +import { EsSummaryDocument } from './summary_transform_generator/helpers/create_temp_summary'; + +const LAG_THRESHOLD_MINUTES = 10; +const STALE_THRESHOLD_MINUTES = 2 * 24 * 60; + +export class GetSLOHealth { + constructor(private esClient: ElasticsearchClient, private repository: SLORepository) {} + + public async execute(params: FetchSLOHealthParams): Promise { + const sloIds = params.list.map(({ sloId }) => sloId); + const sloList = await this.repository.findAllByIds(sloIds); + const sloById = keyBy(sloList, 'id'); + + const filteredList = params.list + .filter((item) => !!sloById[item.sloId]) + .map((item) => ({ + sloId: item.sloId, + sloInstanceId: item.sloInstanceId, + sloRevision: sloById[item.sloId].revision, + })); + + const transformStatsById = await this.getTransformStats(sloList); + const summaryDocsById = await this.getSummaryDocsById(filteredList); + + const results = filteredList.map((item) => { + const health = computeHealth(transformStatsById, item); + const state = computeState(summaryDocsById, item); + + return { + sloId: item.sloId, + sloInstanceId: item.sloInstanceId, + sloRevision: item.sloRevision, + state, + health, + }; + }); + + return fetchSLOHealthResponseSchema.encode(results); + } + + private async getSummaryDocsById( + filteredList: Array<{ sloId: string; sloInstanceId: string; sloRevision: number }> + ) { + const summaryDocs = await this.esClient.search({ + index: SLO_SUMMARY_DESTINATION_INDEX_PATTERN, + query: { + bool: { + should: filteredList.map((item) => ({ + bool: { + must: [ + { term: { 'slo.id': item.sloId } }, + { term: { 'slo.instanceId': item.sloInstanceId } }, + ], + }, + })), + }, + }, + }); + + const summaryDocsById = groupBy( + summaryDocs.hits.hits.map((hit) => hit._source!), + (doc: EsSummaryDocument) => buildSummaryKey(doc.slo.id, doc.slo.instanceId) + ); + return summaryDocsById; + } + + private async getTransformStats( + sloList: SLODefinition[] + ): Promise> { + const transformStats = await this.esClient.transform.getTransformStats( + { + transform_id: sloList + .map((slo: SLODefinition) => [ + getSLOTransformId(slo.id, slo.revision), + getSLOSummaryTransformId(slo.id, slo.revision), + ]) + .flat(), + allow_no_match: true, + size: sloList.length * 2, + }, + { ignore: [404] } + ); + + return keyBy(transformStats.transforms, (transform) => transform.id); + } +} + +function buildSummaryKey(id: string, instanceId: string) { + return id + '|' + instanceId; +} + +function computeState( + summaryDocsById: Dictionary, + item: { sloId: string; sloInstanceId: string; sloRevision: number } +): State { + const sloSummaryDocs = summaryDocsById[buildSummaryKey(item.sloId, item.sloInstanceId)]; + + let state: State = 'no_data'; + if (!sloSummaryDocs) { + return state; + } + const hasOnlyTempSummaryDoc = sloSummaryDocs.every((doc) => doc.isTempDoc); // only temporary documents mean the summary transform did not run yet + const sloSummarydoc = sloSummaryDocs.find((doc) => !doc.isTempDoc); + const latestSliTimestamp = sloSummarydoc?.latestSliTimestamp; + const summaryUpdatedAt = sloSummarydoc?.summaryUpdatedAt; + + if (hasOnlyTempSummaryDoc) { + state = 'no_data'; + } else if (summaryUpdatedAt && latestSliTimestamp) { + const summaryLag = moment().diff(new Date(summaryUpdatedAt), 'minute'); + const indexingLag = moment(summaryUpdatedAt).diff(new Date(latestSliTimestamp), 'minute'); + + // When the summaryUpdatedAt is greater than STALE_THRESHOLD_MINUTES minutes, the SLO is considered stale since no new data triggered a summary document update. + // When the difference between the summaryUpdatedAt and the latestSliTimestamp is + // - Below LAG_THRESHOLD_MINUTES minutes, the SLO has cought up with the sli data, and is running correctly + // - Above LAG_THRESHOLD_MINUTES minutes, the SLO is indexing + if (summaryLag > STALE_THRESHOLD_MINUTES) { + state = 'stale'; + } else { + state = indexingLag >= LAG_THRESHOLD_MINUTES ? 'indexing' : 'running'; + } + } + return state; +} + +function getTransformHealth( + transformStat?: TransformGetTransformStatsTransformStats +): HealthStatus { + return transformStat?.health?.status?.toLowerCase() === 'green' ? 'healthy' : 'unhealthy'; +} + +function computeHealth( + transformStatsById: Dictionary, + item: { sloId: string; sloInstanceId: string; sloRevision: number } +): { overall: HealthStatus; rollup: HealthStatus; summary: HealthStatus } { + const rollup = getTransformHealth( + transformStatsById[getSLOTransformId(item.sloId, item.sloRevision)] + ); + const summary = getTransformHealth( + transformStatsById[getSLOSummaryTransformId(item.sloId, item.sloRevision)] + ); + + const overall: HealthStatus = + rollup === 'healthy' && summary === 'healthy' ? 'healthy' : 'unhealthy'; + + return { overall, rollup, summary }; +} diff --git a/x-pack/plugins/observability_solution/slo/server/services/index.ts b/x-pack/plugins/observability_solution/slo/server/services/index.ts index c9c1ebfc7991c..fd9cf18fa06cb 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/index.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/index.ts @@ -22,3 +22,4 @@ export * from './update_slo'; export * from './summary_client'; export * from './get_slo_instances'; export * from './find_slo_groups'; +export * from './get_slo_health'; diff --git a/x-pack/plugins/observability_solution/slo/server/services/summary_search_client.test.ts b/x-pack/plugins/observability_solution/slo/server/services/summary_search_client.test.ts index bb25e717b6747..8ad2f657d926d 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/summary_search_client.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/summary_search_client.test.ts @@ -8,6 +8,7 @@ import { ElasticsearchClientMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; import { Pagination } from '@kbn/slo-schema/src/models/pagination'; +import { createSLO } from './fixtures/slo'; import { aHitFromSummaryIndex, aHitFromTempSummaryIndex, @@ -43,7 +44,7 @@ describe('Summary Search Client', () => { esClientMock, soClientMock, loggerMock.create(), - 'some-space' + 'default' ); }); @@ -79,11 +80,11 @@ describe('Summary Search Client', () => { }); it('returns the summary documents without duplicate temporary summary documents', async () => { - const SLO_ID1 = 'slo-one'; - const SLO_ID2 = 'slo_two'; - const SLO_ID3 = 'slo-three'; - const SLO_ID4 = 'slo-four'; - const SLO_ID5 = 'slo-five'; + const SLO_ID1 = createSLO({ id: 'slo-one' }); + const SLO_ID2 = createSLO({ id: 'slo_two' }); + const SLO_ID3 = createSLO({ id: 'slo-three' }); + const SLO_ID4 = createSLO({ id: 'slo-four' }); + const SLO_ID5 = createSLO({ id: 'slo-five' }); esClientMock.search.mockResolvedValue({ took: 0, @@ -101,14 +102,14 @@ describe('Summary Search Client', () => { }, max_score: 1, hits: [ - aHitFromSummaryIndex(aSummaryDocument({ id: SLO_ID1 })), - aHitFromSummaryIndex(aSummaryDocument({ id: SLO_ID2 })), - aHitFromSummaryIndex(aSummaryDocument({ id: SLO_ID3 })), - aHitFromSummaryIndex(aSummaryDocument({ id: SLO_ID5 })), // no related temp doc - aHitFromTempSummaryIndex(aSummaryDocument({ id: SLO_ID1, isTempDoc: true })), // removed as dup - aHitFromTempSummaryIndex(aSummaryDocument({ id: SLO_ID2, isTempDoc: true })), // removed as dup - aHitFromTempSummaryIndex(aSummaryDocument({ id: SLO_ID3, isTempDoc: true })), // removed as dup - aHitFromTempSummaryIndex(aSummaryDocument({ id: SLO_ID4, isTempDoc: true })), // kept + aHitFromSummaryIndex(aSummaryDocument(SLO_ID1, { isTempDoc: false })), + aHitFromSummaryIndex(aSummaryDocument(SLO_ID2, { isTempDoc: false })), + aHitFromSummaryIndex(aSummaryDocument(SLO_ID3, { isTempDoc: false })), + aHitFromSummaryIndex(aSummaryDocument(SLO_ID5, { isTempDoc: false })), // no related temp doc + aHitFromTempSummaryIndex(aSummaryDocument(SLO_ID1, { isTempDoc: true })), // removed as dup + aHitFromTempSummaryIndex(aSummaryDocument(SLO_ID2, { isTempDoc: true })), // removed as dup + aHitFromTempSummaryIndex(aSummaryDocument(SLO_ID3, { isTempDoc: true })), // removed as dup + aHitFromTempSummaryIndex(aSummaryDocument(SLO_ID4, { isTempDoc: true })), // kept ], }, }); diff --git a/x-pack/plugins/observability_solution/slo/server/services/summary_transform_generator/helpers/create_temp_summary.ts b/x-pack/plugins/observability_solution/slo/server/services/summary_transform_generator/helpers/create_temp_summary.ts index 4a2a8791bc008..9d4ca3a4afca5 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/summary_transform_generator/helpers/create_temp_summary.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/summary_transform_generator/helpers/create_temp_summary.ts @@ -48,6 +48,8 @@ export interface EsSummaryDocument { isTempDoc: boolean; spaceId: string; kibanaUrl?: string; // >= 8.14 + summaryUpdatedAt: string | null; + latestSliTimestamp: string | null; } export function createTempSummaryDocument( @@ -102,6 +104,8 @@ export function createTempSummaryDocument( isTempDoc: true, spaceId, kibanaUrl: basePath.publicBaseUrl ?? '', // added in 8.14, i.e. might be undefined + summaryUpdatedAt: null, + latestSliTimestamp: null, }; return doc; diff --git a/x-pack/plugins/observability_solution/slo/server/services/unsafe_federated/remote_summary_doc_to_slo.test.ts b/x-pack/plugins/observability_solution/slo/server/services/unsafe_federated/remote_summary_doc_to_slo.test.ts index d32c42e59fa76..cb80fd27d0cc1 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/unsafe_federated/remote_summary_doc_to_slo.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/unsafe_federated/remote_summary_doc_to_slo.test.ts @@ -62,6 +62,8 @@ describe('FromRemoteSummaryDocToSlo', () => { status: 'NO_DATA', isTempDoc: true, spaceId: 'irrelevant', + summaryUpdatedAt: null, + latestSliTimestamp: null, }, loggerMock ); @@ -123,6 +125,8 @@ describe('FromRemoteSummaryDocToSlo', () => { isTempDoc: true, spaceId: 'irrelevant', kibanaUrl: 'http://kibana.com/base-path', // added in 8.14 + summaryUpdatedAt: null, + latestSliTimestamp: null, }, loggerMock ); From f5d7eb6e35a58d37589cb007de50841c766a3896 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 30 Apr 2024 16:28:31 +0200 Subject: [PATCH 046/104] Dashboard filter by creator (#180147) Part of https://github.com/elastic/kibana-team/issues/769 ## Summary This PR adds a "created by" filter to the dashboard listing page. We've added the created_by field recently [here](https://github.com/elastic/kibana/pull/179344) so only newly created by interactive users dashboards will be populated with `created_by` ### Demo Screenshot 2024-04-25 at 16 32 03 Screenshot 2024-04-25 at 16 32 11 ### Implementation notes #### Suggesting users We suggest only the users that have at least one dashboard. We do this by aggregating dashboard saved objects by `created_by`. Because we don't have server-side pagination or sorting yet, in this initial version, I decided to do this client-side to keep it as simple as possible for now. Initially, I did this server-side inside a dashboard plugin as an internal API route. In the long term, this should probably be moved to content management in some form, but it is not clear how it should look yet. This is the commit where I reverted and moved it to client-side https://github.com/elastic/kibana/pull/180147/commits/06316ee8f2fa9a97dd9bf29ae090fc7609027bf3 #### Clint side filtering The user filter is simply a client-side filter because we anyway currently have an in-memory table with client-side sorting and pagination. There is no much practical value in server-side filter atm The filter allows to filter-in by multiple users. It also allows to filter items without creators #### `created_by` filter isn't part of the query string I introduced a separate state for this filter, similar to `tableSort` and `pagination`. The reason why the `created_by` filter isn't a part of the `searchQuery` is because we use `profile_id` which looks ugly for the user, e.g. `u_mGBROF_q5bmFCATLXAcCwKa0k8JvONAwSruelyKA5E_0` so we can't just add it to a user-facing search query like we do with tags. `profile_id` is the correct identified we should use, `username` might not be enough in some cases + `username` in cloud is unreadble account number. The best alternative could be email, but it isn't always available. This is why I decided to keep the `created_by` filter hidden from the user behind the user picker popover and not expose it to the search bar. The `created_by` filter is synced into the URL just like the rest of the table state. #### No distinguishing the current user There is no logic in place that somehow highlights or renames the current user in the filter. This can be added, but to limit the scope of the MVP I didn't do it. #### User filter component We use the `UsersProfilePopover` provided by the security team. We use it without any overrides, so the component decides how to show users in a popover. I noticed a small visual issue with an email truncation in a smaller popover. Might be worth a separate issue. ### Testing 1. Create multiple new users 2. Login for each of them 3. Created a dashboard for each of them 4. Play with the filter #### Next Steps The next step would be to add a column with the user: ![image (5)](https://github.com/elastic/kibana/assets/7784120/9a3fe30e-6a41-4718-a7aa-53fbe0affd22) --- .buildkite/ftr_configs.yml | 1 + .../table_list_view/src/table_list_view.tsx | 3 + .../table_list_view_common/index.ts | 1 + .../src/__jest__/created_by.test.tsx | 202 ++++++++++++++++++ .../src/__jest__/tests.helpers.tsx | 1 + .../table_list_view_table/src/actions.ts | 1 + .../src/components/table.tsx | 94 ++++++-- .../src/components/user_filter_panel.tsx | 187 ++++++++++++++++ .../table_list_view_table/src/mocks.tsx | 1 + .../table_list_view_table/src/reducer.tsx | 4 + .../table_list_view_table/src/services.tsx | 17 ++ .../src/table_list_view_table.tsx | 73 ++++++- .../table_list_view_table/tsconfig.json | 7 +- .../src/saved_object_content_storage.ts | 2 + .../kbn-content-management-utils/src/types.ts | 1 + .../src/user_profiles_selectable.tsx | 24 ++- .../dashboard_listing/dashboard_listing.tsx | 2 + .../dashboard_listing_table.tsx | 4 +- .../use_dashboard_listing_table.test.tsx | 1 + .../hooks/use_dashboard_listing_table.tsx | 2 + src/plugins/dashboard/public/plugin.tsx | 2 +- .../public/services/plugin_services.stub.ts | 2 + .../public/services/plugin_services.ts | 2 + .../dashboard/public/services/types.ts | 2 + .../public/services/user_profile/types.ts | 13 ++ .../user_profile/user_profile_service.stub.ts | 17 ++ .../user_profile/user_profile_service.ts | 22 ++ src/plugins/dashboard/tsconfig.json | 1 + test/functional/services/listing_table.ts | 29 +++ .../__snapshots__/oss_features.test.ts.snap | 8 + .../plugins/features/server/oss_features.ts | 2 + .../apis/content_management/config.ts | 17 ++ .../apis/content_management/created_by.ts | 59 +++++ .../apis/content_management/helpers.ts | 74 +++++++ .../apis/content_management/index.ts | 14 ++ .../apps/dashboard/group1/created_by.ts | 63 ++++++ .../functional/apps/dashboard/group1/index.ts | 1 + 37 files changed, 925 insertions(+), 31 deletions(-) create mode 100644 packages/content-management/table_list_view_table/src/__jest__/created_by.test.tsx create mode 100644 packages/content-management/table_list_view_table/src/components/user_filter_panel.tsx create mode 100644 src/plugins/dashboard/public/services/user_profile/types.ts create mode 100644 src/plugins/dashboard/public/services/user_profile/user_profile_service.stub.ts create mode 100644 src/plugins/dashboard/public/services/user_profile/user_profile_service.ts create mode 100644 x-pack/test/api_integration/apis/content_management/config.ts create mode 100644 x-pack/test/api_integration/apis/content_management/created_by.ts create mode 100644 x-pack/test/api_integration/apis/content_management/helpers.ts create mode 100644 x-pack/test/api_integration/apis/content_management/index.ts create mode 100644 x-pack/test/functional/apps/dashboard/group1/created_by.ts diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index b792825bd9dcf..ac9ccb04c68e2 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -192,6 +192,7 @@ enabled: - x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts - x-pack/test/api_integration/apis/asset_manager/config_when_enabled.ts - x-pack/test/api_integration/apis/cases/config.ts + - x-pack/test/api_integration/apis/content_management/config.ts - x-pack/test/api_integration/apis/cloud_security_posture/config.ts - x-pack/test/api_integration/apis/console/config.ts - x-pack/test/api_integration/apis/es/config.ts diff --git a/packages/content-management/table_list_view/src/table_list_view.tsx b/packages/content-management/table_list_view/src/table_list_view.tsx index 1fd8cc8cc70c2..a5150c959e4f5 100644 --- a/packages/content-management/table_list_view/src/table_list_view.tsx +++ b/packages/content-management/table_list_view/src/table_list_view.tsx @@ -37,6 +37,7 @@ export type TableListViewProps & { title: string; description?: string; @@ -73,6 +74,7 @@ export const TableListView = ({ titleColumnName, additionalRightSideActions, withoutPageTemplateWrapper, + createdByEnabled, }: TableListViewProps) => { const PageTemplate = withoutPageTemplateWrapper ? (React.Fragment as unknown as typeof KibanaPageTemplate) @@ -121,6 +123,7 @@ export const TableListView = ({ withoutPageTemplateWrapper={withoutPageTemplateWrapper} onFetchSuccess={onFetchSuccess} setPageDataTestSubject={setPageDataTestSubject} + createdByEnabled={createdByEnabled} /> diff --git a/packages/content-management/table_list_view_common/index.ts b/packages/content-management/table_list_view_common/index.ts index 4ee102fb1e9a8..fea9e6a918673 100644 --- a/packages/content-management/table_list_view_common/index.ts +++ b/packages/content-management/table_list_view_common/index.ts @@ -11,6 +11,7 @@ import type { SavedObjectsReference } from '@kbn/content-management-content-edit export interface UserContentCommonSchema { id: string; updatedAt: string; + createdBy?: string; managed?: boolean; references: SavedObjectsReference[]; type: string; diff --git a/packages/content-management/table_list_view_table/src/__jest__/created_by.test.tsx b/packages/content-management/table_list_view_table/src/__jest__/created_by.test.tsx new file mode 100644 index 0000000000000..f4a28d0c333cf --- /dev/null +++ b/packages/content-management/table_list_view_table/src/__jest__/created_by.test.tsx @@ -0,0 +1,202 @@ +/* + * 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 { MemoryRouter } from 'react-router-dom'; +import { render, screen, within, waitForElementToBeRemoved } from '@testing-library/react'; +import { I18nProvider } from '@kbn/i18n-react'; +import { WithServices } from './tests.helpers'; +import { TableListViewTable, type TableListViewTableProps } from '../table_list_view_table'; +import type { UserContentCommonSchema } from '@kbn/content-management-table-list-view-common'; +import userEvent from '@testing-library/user-event'; + +const hits: UserContentCommonSchema[] = [ + { + id: 'item-1', + type: 'dashboard', + updatedAt: '2020-01-01T00:00:00Z', + attributes: { + title: 'Item 1', + }, + references: [], + }, + { + id: 'item-2', + type: 'dashboard', + updatedAt: '2020-01-01T00:00:00Z', + attributes: { + title: 'Item 2', + }, + createdBy: 'u_1', + references: [], + }, + { + id: 'item-3', + type: 'dashboard', + updatedAt: '2020-01-01T00:00:00Z', + attributes: { + title: 'Item 3', + }, + createdBy: 'u_2', + references: [], + }, +]; + +describe('created_by', () => { + const requiredProps: TableListViewTableProps = { + entityName: 'test', + entityNamePlural: 'tests', + listingLimit: 500, + initialFilter: '', + initialPageSize: 20, + findItems: jest.fn().mockResolvedValue({ total: 0, hits }), + getDetailViewLink: () => 'http://elastic.co', + urlStateEnabled: false, + onFetchSuccess: () => {}, + tableCaption: 'my caption', + setPageDataTestSubject: () => {}, + }; + + const mockBulkGetUserProfiles = jest.fn((uids) => + Promise.resolve( + [ + { + uid: 'u_1', + enabled: true, + user: { + username: 'user1', + }, + data: {}, + }, + { + uid: 'u_2', + enabled: true, + user: { + username: 'user2', + }, + data: {}, + }, + ].filter((user) => uids.includes(user.uid)) + ) + ); + + const TableListViewWithServices = WithServices(TableListViewTable, { + bulkGetUserProfiles: mockBulkGetUserProfiles, + }); + const TableListView = (overrides: Partial) => ( + + + + + + ); + + test("shouldn't render created by filter when createdBy is disabled", async () => { + render(); + + // wait until first render + expect(await screen.findByTestId('itemsInMemTable')).toBeVisible(); + + expect(() => screen.getByTestId('userFilterPopoverButton')).toThrow(); + }); + + test('should be able to filter by creators', async () => { + render(); + + // wait until first render + expect(await screen.findByTestId('itemsInMemTable')).toBeVisible(); + + // 3 items in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(3); + + userEvent.click(screen.getByTestId('userFilterPopoverButton')); + + const userSelectablePopover = screen.getByTestId('userSelectableList'); + const popover = within(userSelectablePopover); + expect(await popover.findAllByTestId(/userProfileSelectableOption/)).toHaveLength(3); + + userEvent.click(popover.getByTestId('userProfileSelectableOption-user1')); + + // 2 item in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(1); + + userEvent.click(popover.getByTestId('userProfileSelectableOption-user2')); + + // 2 item in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(2); + }); + + test('should be able to filter by "no creators"', async () => { + render(); + + // wait until first render + expect(await screen.findByTestId('itemsInMemTable')).toBeVisible(); + + // 3 items in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(3); + + userEvent.click(screen.getByTestId('userFilterPopoverButton')); + + const userSelectablePopover = screen.getByTestId('userSelectableList'); + const popover = within(userSelectablePopover); + userEvent.click(await popover.findByTestId('userProfileSelectableOption-null')); + + // just 1 item in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(1); + }); + + test('"no creators" options shouldn\'t appear if all objects have creators', async () => { + render( + ({ + hits: [hits[1], hits[2]], + total: 2, + })} + /> + ); + + // wait until first render + expect(await screen.findByTestId('itemsInMemTable')).toBeVisible(); + // 2 items in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(2); + + userEvent.click(screen.getByTestId('userFilterPopoverButton')); + + const userSelectablePopover = screen.getByTestId('userSelectableList'); + const popover = within(userSelectablePopover); + expect(await popover.findAllByTestId(/userProfileSelectableOption/)).toHaveLength(2); + expect(() => popover.getByTestId('userProfileSelectableOption-null')).toThrow(); + }); + + test('empty message in case no objects have creators', async () => { + render( + ({ + hits: [hits[0]], + total: 1, + })} + /> + ); + + // wait until first render + expect(await screen.findByTestId('itemsInMemTable')).toBeVisible(); + // 1 item in the list + expect(screen.getAllByTestId(/userContentListingTitleLink/)).toHaveLength(1); + + userEvent.click(screen.getByTestId('userFilterPopoverButton')); + + const userSelectablePopover = screen.getByTestId('userSelectableList'); + const popover = within(userSelectablePopover); + await waitForElementToBeRemoved(() => popover.getByRole('progressbar')); + expect(popover.getAllByTestId('userFilterEmptyMessage')[1]).toBeVisible(); + }); +}); diff --git a/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx b/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx index 5fb8b605d9202..baca088ac8985 100644 --- a/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx +++ b/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx @@ -25,6 +25,7 @@ export const getMockServices = (overrides?: Partial) => { itemHasTags: () => true, getTagManagementUrl: () => '', getTagIdsFromReferences: () => [], + bulkGetUserProfiles: jest.fn(() => Promise.resolve([])), ...overrides, }; diff --git a/packages/content-management/table_list_view_table/src/actions.ts b/packages/content-management/table_list_view_table/src/actions.ts index 4ae4686779746..8f3e2efe9f86b 100644 --- a/packages/content-management/table_list_view_table/src/actions.ts +++ b/packages/content-management/table_list_view_table/src/actions.ts @@ -57,6 +57,7 @@ export interface OnTableChangeAction { pageIndex: number; pageSize: number; }; + filter?: Partial['tableFilter']>; }; } diff --git a/packages/content-management/table_list_view_table/src/components/table.tsx b/packages/content-management/table_list_view_table/src/components/table.tsx index a459bc26ede50..475b4557740ac 100644 --- a/packages/content-management/table_list_view_table/src/components/table.tsx +++ b/packages/content-management/table_list_view_table/src/components/table.tsx @@ -35,10 +35,15 @@ import { TagFilterPanel } from './tag_filter_panel'; import { useTagFilterPanel } from './use_tag_filter_panel'; import type { Params as UseTagFilterPanelParams } from './use_tag_filter_panel'; import type { SortColumnField } from './table_sort_select'; +import { + UserFilterPanel, + UserFilterContextProvider, + NULL_USER as USER_FILTER_NULL_USER, +} from './user_filter_panel'; type State = Pick< TableListViewState, - 'items' | 'selectedIds' | 'searchQuery' | 'tableSort' | 'pagination' + 'items' | 'selectedIds' | 'searchQuery' | 'tableSort' | 'pagination' | 'tableFilter' >; type TagManagementProps = Pick< @@ -59,8 +64,10 @@ interface Props extends State, TagManageme renderCreateButton: () => React.ReactElement | undefined; onSortChange: (column: SortColumnField, direction: Direction) => void; onTableChange: (criteria: CriteriaWithPagination) => void; + onFilterChange: (filter: Partial['tableFilter']>) => void; onTableSearchChange: (arg: { query: Query | null; queryText: string }) => void; clearTagSelection: () => void; + createdByEnabled: boolean; } export function Table({ @@ -72,6 +79,7 @@ export function Table({ pagination, tableColumns, tableSort, + tableFilter, hasUpdatedAtMetadata, entityName, entityNamePlural, @@ -83,9 +91,11 @@ export function Table({ onTableChange, onTableSearchChange, onSortChange, + onFilterChange, addOrRemoveExcludeTagFilter, addOrRemoveIncludeTagFilter, clearTagSelection, + createdByEnabled, }: Props) { const { getTagList } = useServices(); @@ -200,9 +210,20 @@ export function Table({ clearTagSelection, ]); + const userFilterPanel = useMemo(() => { + return createdByEnabled + ? { + type: 'custom_component', + component: UserFilterPanel, + } + : null; + }, [createdByEnabled]); + const searchFilters = useMemo(() => { - return [tableSortSelectFilter, tagFilterPanel]; - }, [tableSortSelectFilter, tagFilterPanel]); + return [tableSortSelectFilter, tagFilterPanel, userFilterPanel].filter( + (f: SearchFilterConfig | null): f is SearchFilterConfig => Boolean(f) + ); + }, [tableSortSelectFilter, tagFilterPanel, userFilterPanel]); const search = useMemo((): Search => { return { @@ -226,22 +247,57 @@ export function Table({ /> ); + const visibleItems = React.useMemo(() => { + if (tableFilter?.createdBy?.length > 0) { + return items.filter((item) => { + if (item.createdBy) return tableFilter.createdBy.includes(item.createdBy); + else return tableFilter.createdBy.includes(USER_FILTER_NULL_USER); + }); + } + + return items; + }, [items, tableFilter]); + + const { allUsers, showNoUserOption } = useMemo(() => { + if (!createdByEnabled) return { allUsers: [], showNoUserOption: false }; + + let _showNoUserOption = false; + const users = new Set(); + items.forEach((item) => { + if (item.createdBy) users.add(item.createdBy); + else { + _showNoUserOption = true; + } + }); + return { allUsers: Array.from(users), showNoUserOption: _showNoUserOption }; + }, [createdByEnabled, items]); + return ( - - itemId="id" - items={items} - columns={tableColumns} - pagination={pagination} - loading={isFetchingItems} - message={noItemsMessage} - selection={selection} - search={search} - executeQueryOptions={{ enabled: false }} - sorting={tableSort ? { sort: tableSort as PropertySort } : undefined} - onChange={onTableChange} - data-test-subj="itemsInMemTable" - rowHeader="attributes.title" - tableCaption={tableCaption} - /> + { + onFilterChange({ createdBy: selectedUsers }); + }} + selectedUsers={tableFilter.createdBy} + showNoUserOption={showNoUserOption} + > + + itemId="id" + items={visibleItems} + columns={tableColumns} + pagination={pagination} + loading={isFetchingItems} + message={noItemsMessage} + selection={selection} + search={search} + executeQueryOptions={{ enabled: false }} + sorting={tableSort ? { sort: tableSort as PropertySort } : undefined} + onChange={onTableChange} + data-test-subj="itemsInMemTable" + rowHeader="attributes.title" + tableCaption={tableCaption} + /> + ); } diff --git a/packages/content-management/table_list_view_table/src/components/user_filter_panel.tsx b/packages/content-management/table_list_view_table/src/components/user_filter_panel.tsx new file mode 100644 index 0000000000000..82a2838ab44e3 --- /dev/null +++ b/packages/content-management/table_list_view_table/src/components/user_filter_panel.tsx @@ -0,0 +1,187 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { FC } from 'react'; +import React from 'react'; +import { EuiFilterButton, EuiIconTip, useEuiTheme } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { UserProfile, UserProfilesPopover } from '@kbn/user-profile-components'; +import { useQuery, QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { i18n } from '@kbn/i18n'; +import { useServices } from '../services'; + +interface Context { + enabled: boolean; + onSelectedUsersChange: (users: string[]) => void; + selectedUsers: string[]; + allUsers: string[]; + showNoUserOption: boolean; +} + +const UserFilterContext = React.createContext(null); +const queryClient = new QueryClient({ + defaultOptions: { queries: { retry: false, staleTime: 30 * 60 * 1000 } }, +}); + +export const UserFilterContextProvider: FC = ({ children, ...props }) => { + if (!props.enabled) { + return <>{children}; + } + + return ( + + {children} + + ); +}; + +export const NULL_USER = 'no-user'; + +export const UserFilterPanel: FC<{}> = () => { + const { bulkGetUserProfiles } = useServices(); + const { euiTheme } = useEuiTheme(); + const componentContext = React.useContext(UserFilterContext); + if (!componentContext) + throw new Error('UserFilterPanel must be used within a UserFilterContextProvider'); + if (!bulkGetUserProfiles) + throw new Error('UserFilterPanel must be used with a bulkGetUserProfiles function'); + + const { onSelectedUsersChange, selectedUsers, showNoUserOption } = componentContext; + + const [isPopoverOpen, setPopoverOpen] = React.useState(false); + const [searchTerm, setSearchTerm] = React.useState(''); + + const query = useQuery({ + queryKey: ['user-filter-suggestions', componentContext.allUsers], + queryFn: () => bulkGetUserProfiles(componentContext.allUsers), + enabled: isPopoverOpen, + }); + + const usersMap = React.useMemo(() => { + if (!query.data) return {}; + return query.data.reduce((acc, user) => { + acc[user.uid] = user; + return acc; + }, {} as Record); + }, [query.data]); + + const visibleOptions = React.useMemo(() => { + if (!query.data || query.data.length === 0) return []; + // attach null to the end of the list to represent the "no creator" option + const users = + showNoUserOption || selectedUsers.includes(NULL_USER) ? [...query.data, null] : query.data; + + if (!searchTerm) { + return users; + } + + return users.filter((user) => { + // keep the "no creator" option if it's selected + if (!user) { + return selectedUsers.includes(NULL_USER); + } + + // keep the user if it's selected + if (selectedUsers.includes(user.uid)) return true; + + // filter only users that match the search term + const searchString = ( + user.uid + + user.user.username + + (user.user.email ?? '') + + (user.user.full_name ?? '') + ).toLowerCase(); + return searchString.includes(searchTerm.toLowerCase()); + }); + }, [query.data, searchTerm, selectedUsers, showNoUserOption]); + + const noUsersTip = ( + + } + /> + ); + + return ( + <> + setPopoverOpen(!isPopoverOpen)} + hasActiveFilters={selectedUsers.length > 0} + numActiveFilters={selectedUsers.length} + grow + > + + + } + isOpen={isPopoverOpen} + closePopover={() => setPopoverOpen(false)} + selectableProps={{ + 'data-test-subj': 'userSelectableList', + isLoading: query.isLoading, + options: visibleOptions, + errorMessage: query.error ? ( + + ) : undefined, + emptyMessage: ( +

    + + {noUsersTip} +

    + ), + nullOptionLabel: i18n.translate( + 'contentManagement.tableList.listing.userFilter.noCreators', + { + defaultMessage: 'No creators', + } + ), + nullOptionProps: { + append: noUsersTip, + }, + clearButtonLabel: ( + + ), + selectedOptions: selectedUsers.map((uid) => + uid === NULL_USER ? null : usersMap[uid] ?? { uid, user: { username: uid } } + ), + onChange: (options) => { + onSelectedUsersChange(options.map((option) => (option ? option.uid : NULL_USER))); + }, + onSearchChange: setSearchTerm, + }} + panelProps={{ css: { minWidth: euiTheme.base * 18 } }} + /> + + ); +}; diff --git a/packages/content-management/table_list_view_table/src/mocks.tsx b/packages/content-management/table_list_view_table/src/mocks.tsx index bbdfc3e9f9c7b..da1bc983c3041 100644 --- a/packages/content-management/table_list_view_table/src/mocks.tsx +++ b/packages/content-management/table_list_view_table/src/mocks.tsx @@ -71,6 +71,7 @@ export const getStoryServices = (params: Params, action: ActionFn = () => {}) => itemHasTags: () => true, getTagManagementUrl: () => '', getTagIdsFromReferences: () => [], + bulkGetUserProfiles: () => Promise.resolve([]), ...params, }; diff --git a/packages/content-management/table_list_view_table/src/reducer.tsx b/packages/content-management/table_list_view_table/src/reducer.tsx index be6b8d4043ebd..bf4e912f84394 100644 --- a/packages/content-management/table_list_view_table/src/reducer.tsx +++ b/packages/content-management/table_list_view_table/src/reducer.tsx @@ -93,6 +93,9 @@ export function getReducer() { const tableSort = action.data.sort ?? state.tableSort; const pageIndex = action.data.page?.pageIndex ?? state.pagination.pageIndex; const pageSize = action.data.page?.pageSize ?? state.pagination.pageSize; + const tableFilter = action.data.filter + ? { ...state.tableFilter, ...action.data.filter } + : state.tableFilter; return { ...state, @@ -102,6 +105,7 @@ export function getReducer() { pageSize, }, tableSort, + tableFilter, }; } case 'showConfirmDeleteItemsModal': { diff --git a/packages/content-management/table_list_view_table/src/services.tsx b/packages/content-management/table_list_view_table/src/services.tsx index 612985ed6d331..de5e5b520bbd7 100644 --- a/packages/content-management/table_list_view_table/src/services.tsx +++ b/packages/content-management/table_list_view_table/src/services.tsx @@ -11,6 +11,8 @@ import type { Observable } from 'rxjs'; import type { FormattedRelative } from '@kbn/i18n-react'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; import type { OverlayFlyoutOpenOptions } from '@kbn/core-overlays-browser'; +import type { UserProfileServiceStart } from '@kbn/core-user-profile-browser'; +import type { UserProfile } from '@kbn/core-user-profile-common'; import { RedirectAppLinksKibanaProvider } from '@kbn/shared-ux-link-redirect-app'; import { ContentEditorKibanaProvider, @@ -58,6 +60,8 @@ export interface Services { /** Handler to return the url to navigate to the kibana tags management */ getTagManagementUrl: () => string; getTagIdsFromReferences: (references: SavedObjectsReference[]) => string[]; + /** resolve user profiles for the user filter and creator functionality */ + bulkGetUserProfiles: (uids: string[]) => Promise; } const TableListViewContext = React.createContext(null); @@ -104,6 +108,9 @@ export interface TableListViewKibanaDependencies { readonly darkMode: boolean; }>; }; + userProfile: { + bulkGet: UserProfileServiceStart['bulkGet']; + }; }; /** * Handler from the '@kbn/kibana-react-plugin/public' Plugin @@ -218,6 +225,15 @@ export const TableListViewKibanaProvider: FC< [getTagIdsFromReferences] ); + const bulkGetUserProfiles = useCallback<(userProfileIds: string[]) => Promise>( + async (uids: string[]) => { + if (uids.length === 0) return []; + + return core.userProfile.bulkGet({ uids: new Set(uids), dataPath: 'avatar' }); + }, + [core.userProfile] + ); + return ( core.http.basePath.prepend(TAG_MANAGEMENT_APP_URL)} + bulkGetUserProfiles={bulkGetUserProfiles} > {children} diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx index 00f28114f3da0..6c6ed5c9631c4 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx @@ -65,6 +65,7 @@ export interface TableListViewTableProps< /** Add an additional custom column */ customTableColumn?: EuiBasicTableColumn; urlStateEnabled?: boolean; + createdByEnabled?: boolean; /** * Id of the heading element describing the table. This id will be used as `aria-labelledby` of the wrapper element. * If the table is not empty, this component renders its own h1 element using the same id. @@ -140,6 +141,9 @@ export interface State { } } + if (sanitizedParams.created_by) { + stateFromURL.filter = { + createdBy: Array.isArray(sanitizedParams.created_by) + ? sanitizedParams.created_by + : [sanitizedParams.created_by], + }; + } else { + stateFromURL.filter = { createdBy: [] }; + } + return stateFromURL; }; @@ -207,6 +225,7 @@ const urlStateDeserializer = (params: URLQueryParams): URLState => { const urlStateSerializer = (updated: { s?: string; sort?: { field: 'title' | 'updatedAt'; direction: Direction }; + filter?: { createdBy?: string[] }; }) => { const updatedQueryParams: Partial = {}; @@ -225,6 +244,10 @@ const urlStateSerializer = (updated: { updatedQueryParams.title = undefined; } + if (updated.filter?.createdBy) { + updatedQueryParams.created_by = updated.filter.createdBy; + } + return updatedQueryParams; }; @@ -264,6 +287,7 @@ function TableListViewTableComp({ onFetchSuccess, refreshListBouncer, setPageDataTestSubject, + createdByEnabled = false, }: TableListViewTableProps) { useEffect(() => { setPageDataTestSubject(`${entityName}LandingPage`); @@ -345,6 +369,9 @@ function TableListViewTableComp({ field: 'attributes.title' as const, direction: 'asc', }, + tableFilter: { + createdBy: [], + }, }), [initialPageSize] ); @@ -365,6 +392,7 @@ function TableListViewTableComp({ hasUpdatedAtMetadata, pagination, tableSort, + tableFilter, } = state; const showFetchError = Boolean(fetchError); @@ -700,13 +728,14 @@ function TableListViewTableComp({ [updateQuery, buildQueryFromText] ); - const updateTableSortAndPagination = useCallback( + const updateTableSortFilterAndPagination = useCallback( (data: { sort?: State['tableSort']; page?: { pageIndex: number; pageSize: number; }; + filter?: Partial['tableFilter']>; }) => { if (data.sort && urlStateEnabled) { setUrlState({ @@ -717,6 +746,12 @@ function TableListViewTableComp({ }); } + if (data.filter && urlStateEnabled) { + setUrlState({ + filter: data.filter, + }); + } + if (data.page || !urlStateEnabled) { dispatch({ type: 'onTableChange', @@ -729,14 +764,23 @@ function TableListViewTableComp({ const onSortChange = useCallback( (field: SortColumnField, direction: Direction) => { - updateTableSortAndPagination({ + updateTableSortFilterAndPagination({ sort: { field, direction, }, }); }, - [updateTableSortAndPagination] + [updateTableSortFilterAndPagination] + ); + + const onFilterChange = useCallback( + (filter: Partial) => { + updateTableSortFilterAndPagination({ + filter, + }); + }, + [updateTableSortFilterAndPagination] ); const onTableChange = useCallback( @@ -770,9 +814,9 @@ function TableListViewTableComp({ pageSize: criteria.page.size, }; - updateTableSortAndPagination(data); + updateTableSortFilterAndPagination(data); }, - [updateTableSortAndPagination] + [updateTableSortFilterAndPagination] ); const deleteSelectedItems = useCallback(async () => { @@ -911,8 +955,24 @@ function TableListViewTableComp({ }); }; + const updateFilterFromURL = (filter?: URLState['filter']) => { + if (!filter) { + return; + } + + dispatch({ + type: 'onTableChange', + data: { + filter: { + createdBy: filter.createdBy ?? [], + }, + }, + }); + }; + updateQueryFromURL(urlState.s); updateSortFromURL(urlState.sort); + updateFilterFromURL(urlState.filter); }, [urlState, buildQueryFromText, urlStateEnabled]); useEffect(() => { @@ -996,6 +1056,7 @@ function TableListViewTableComp({ tableColumns={tableColumns} hasUpdatedAtMetadata={hasUpdatedAtMetadata} tableSort={tableSort} + tableFilter={tableFilter} tableItemsRowActions={tableItemsRowActions} pagination={pagination} selectedIds={selectedIds} @@ -1007,9 +1068,11 @@ function TableListViewTableComp({ onTableChange={onTableChange} onTableSearchChange={onTableSearchChange} onSortChange={onSortChange} + onFilterChange={onFilterChange} addOrRemoveIncludeTagFilter={addOrRemoveIncludeTagFilter} addOrRemoveExcludeTagFilter={addOrRemoveExcludeTagFilter} clearTagSelection={clearTagSelection} + createdByEnabled={createdByEnabled} /> {/* Delete modal */} diff --git a/packages/content-management/table_list_view_table/tsconfig.json b/packages/content-management/table_list_view_table/tsconfig.json index 6837cecb7eeb9..579e372eb7950 100644 --- a/packages/content-management/table_list_view_table/tsconfig.json +++ b/packages/content-management/table_list_view_table/tsconfig.json @@ -8,7 +8,9 @@ "react", "@kbn/ambient-ui-types", "@kbn/ambient-storybook-types", - "@emotion/react/types/css-prop" + "@emotion/react/types/css-prop", + "@testing-library/jest-dom", + "@testing-library/react" ] }, "include": [ @@ -26,6 +28,9 @@ "@kbn/shared-ux-link-redirect-app", "@kbn/test-jest-helpers", "@kbn/content-management-table-list-view-common", + "@kbn/user-profile-components", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-common", ], "exclude": [ "target/**/*", diff --git a/packages/kbn-content-management-utils/src/saved_object_content_storage.ts b/packages/kbn-content-management-utils/src/saved_object_content_storage.ts index 070bb9cd5d739..d462c7a02b8de 100644 --- a/packages/kbn-content-management-utils/src/saved_object_content_storage.ts +++ b/packages/kbn-content-management-utils/src/saved_object_content_storage.ts @@ -65,6 +65,7 @@ function savedObjectToItem( type, updated_at: updatedAt, created_at: createdAt, + created_by: createdBy, attributes, references, error, @@ -79,6 +80,7 @@ function savedObjectToItem( managed, updatedAt, createdAt, + createdBy, attributes: pick(attributes, allowedSavedObjectAttributes), references, error, diff --git a/packages/kbn-content-management-utils/src/types.ts b/packages/kbn-content-management-utils/src/types.ts index f350da4f82cf9..72f2093acf2ad 100644 --- a/packages/kbn-content-management-utils/src/types.ts +++ b/packages/kbn-content-management-utils/src/types.ts @@ -194,6 +194,7 @@ export interface SOWithMetadata { version?: string; createdAt?: string; updatedAt?: string; + createdBy?: string; error?: { error: string; message: string; diff --git a/packages/kbn-user-profile-components/src/user_profiles_selectable.tsx b/packages/kbn-user-profile-components/src/user_profiles_selectable.tsx index 3f36c0806a56e..1b08d55928b73 100644 --- a/packages/kbn-user-profile-components/src/user_profiles_selectable.tsx +++ b/packages/kbn-user-profile-components/src/user_profiles_selectable.tsx @@ -44,6 +44,7 @@ export interface UserProfilesSelectableProps
    ))} diff --git a/src/plugins/presentation_util/tsconfig.json b/src/plugins/presentation_util/tsconfig.json index 8101d5b27a575..dc386db112c16 100644 --- a/src/plugins/presentation_util/tsconfig.json +++ b/src/plugins/presentation_util/tsconfig.json @@ -34,6 +34,7 @@ "@kbn/shared-ux-button-toolbar", "@kbn/code-editor", "@kbn/calculate-width-from-char-count", + "@kbn/field-utils", ], "exclude": ["target/**/*"] } From 0762c6ef882d436188ec422463699ee2d89bf0ec Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 30 Apr 2024 19:55:28 +0100 Subject: [PATCH 066/104] skip flaky suite (#182126) --- .../functional/test_suites/common/discover/group2/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts index 658b92845ffca..be8a043327a7d 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts @@ -11,7 +11,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); - describe('discover/group2', function () { + // FLAKY: https://github.com/elastic/kibana/issues/182126 + describe.skip('discover/group2', function () { before(async function () { await browser.setWindowSize(1600, 1200); }); From fe4ef48848647fc50a1206453a3e13d19ff625cc Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 30 Apr 2024 20:04:00 +0100 Subject: [PATCH 067/104] skip flaky suite (#182125) --- .../test_suites/common/discover/group2/_data_grid_doc_table.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts index 2ca4c5f856937..3745b1223d615 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts @@ -33,7 +33,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const security = getService('security'); - describe('discover data grid doc table', function describeIndexTests() { + // FLAKY: https://github.com/elastic/kibana/issues/182125 + describe.skip('discover data grid doc table', function describeIndexTests() { before(async function () { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); log.debug('load kibana index with default index pattern'); From 74f7125ef369e4bc2b56832b0c9f99c8be6a9c2d Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 30 Apr 2024 20:05:27 +0100 Subject: [PATCH 068/104] skip flaky suite (#182154) --- .../functional/apps/dataset_quality/dataset_quality_flyout.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/dataset_quality/dataset_quality_flyout.ts b/x-pack/test/functional/apps/dataset_quality/dataset_quality_flyout.ts index c0d92c07811ee..8e1abbbefa9dc 100644 --- a/x-pack/test/functional/apps/dataset_quality/dataset_quality_flyout.ts +++ b/x-pack/test/functional/apps/dataset_quality/dataset_quality_flyout.ts @@ -28,7 +28,8 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid const browser = getService('browser'); const to = '2024-01-01T12:00:00.000Z'; - describe('Dataset quality flyout', () => { + // FLAKY: https://github.com/elastic/kibana/issues/182154 + describe.skip('Dataset quality flyout', () => { before(async () => { await synthtrace.index(getInitialTestLogs({ to, count: 4 })); await PageObjects.datasetQuality.navigateTo(); From 3f01c4060d7caa083a85cd20cd6467aa9124c361 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 30 Apr 2024 20:06:56 +0100 Subject: [PATCH 069/104] skip flaky suite (#174068) --- .../e2e/investigations/timelines/unsaved_timeline.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/unsaved_timeline.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/unsaved_timeline.cy.ts index fb7e0652293e8..1c46f8491f986 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/unsaved_timeline.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/unsaved_timeline.cy.ts @@ -37,7 +37,8 @@ import { } from '../../../tasks/timeline'; import { EXPLORE_URL, hostsUrl, MANAGE_URL } from '../../../urls/navigation'; -describe('[ESS] Save Timeline Prompts', { tags: ['@ess'] }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/174068 +describe.skip('[ESS] Save Timeline Prompts', { tags: ['@ess'] }, () => { beforeEach(() => { login(); visitWithTimeRange(hostsUrl('allHosts')); From a0e269c00afce5ccf884dccaa5114ed18db84487 Mon Sep 17 00:00:00 2001 From: christineweng <18648970+christineweng@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:16:11 -0500 Subject: [PATCH 070/104] [Security Solution] Enable expandable flyout for events (#182178) ## Summary This PR enables expandable flyout for events by default. ![image](https://github.com/elastic/kibana/assets/18648970/f686b41b-9ceb-4d52-9764-d203c783e15b) --- .../plugins/security_solution/common/experimental_features.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 18b13eb3dd193..3ad99b95905bb 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -120,7 +120,7 @@ export const allowedExperimentalValues = Object.freeze({ /** * Enables expandable flyout for event type documents */ - expandableEventFlyoutEnabled: false, + expandableEventFlyoutEnabled: true, /** * Enables expandable flyout in timeline From daf81a6b937adf4ed8feab3a436a37f00379ebc8 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 30 Apr 2024 13:57:40 -0600 Subject: [PATCH 071/104] rename SerializedMapState to ParsedMapStateJSON and SerializedUiState to ParsedUiStateJSON (#182185) Part of https://github.com/elastic/kibana/issues/174960 https://github.com/elastic/kibana/pull/178158 creates a new type `MapSerializeState`. This new type name is very confusing with existing `SerializedMapState` type name. This PR renames `SerializedMapState` to `ParsedMapStateJSON` to avoid this confusion. Breaking this change out of https://github.com/elastic/kibana/issues/174960 to make things clearer and avoid confusion during reviewing https://github.com/elastic/kibana/issues/174960 --- .../routes/map_page/map_app/map_app.tsx | 24 +++++++++---------- .../map_page/saved_map/get_initial_query.ts | 10 ++++---- .../saved_map/get_initial_refresh_config.ts | 10 ++++---- .../public/routes/map_page/saved_map/index.ts | 2 +- .../routes/map_page/saved_map/saved_map.ts | 18 +++++++------- .../public/routes/map_page/saved_map/types.ts | 4 ++-- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 4bb8ed74a8195..94c993c6aeff4 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -62,7 +62,7 @@ import { unsavedChangesWarning, } from '../saved_map'; import { waitUntilTimeLayersLoad$ } from './wait_until_time_layers_load'; -import { RefreshConfig as MapRefreshConfig, SerializedMapState } from '../saved_map'; +import { RefreshConfig as MapRefreshConfig, ParsedMapStateJSON } from '../saved_map'; export interface Props { savedMap: SavedMap; @@ -310,24 +310,24 @@ export class MapApp extends React.Component { this._updateGlobalState(updatedGlobalState); }; - _getInitialTime(serializedMapState?: SerializedMapState) { + _getInitialTime(mapState?: ParsedMapStateJSON) { if (this._initialTimeFromUrl) { return this._initialTimeFromUrl; } - return !this.props.savedMap.hasSaveAndReturnConfig() && serializedMapState?.timeFilters - ? serializedMapState.timeFilters + return !this.props.savedMap.hasSaveAndReturnConfig() && mapState?.timeFilters + ? mapState.timeFilters : getTimeFilter().getTime(); } - _initMapAndLayerSettings(serializedMapState?: SerializedMapState) { + _initMapAndLayerSettings(mapState?: ParsedMapStateJSON) { const globalState = this._getGlobalState(); - const savedObjectFilters = serializedMapState?.filters ? serializedMapState.filters : []; + const savedObjectFilters = mapState?.filters ? mapState.filters : []; const appFilters = this._appStateManager.getFilters() || []; const query = getInitialQuery({ - serializedMapState, + mapState, appState: this._appStateManager.getAppState(), }); if (query) { @@ -337,12 +337,12 @@ export class MapApp extends React.Component { this._onQueryChange({ filters: [..._.get(globalState, 'filters', []), ...appFilters, ...savedObjectFilters], query, - time: this._getInitialTime(serializedMapState), + time: this._getInitialTime(mapState), }); this._onRefreshConfigChange( getInitialRefreshConfig({ - serializedMapState, + mapState, globalState, }) ); @@ -453,16 +453,16 @@ export class MapApp extends React.Component { ); } - let serializedMapState: SerializedMapState | undefined; + let mapState: ParsedMapStateJSON | undefined; try { const attributes = this.props.savedMap.getAttributes(); if (attributes.mapStateJSON) { - serializedMapState = JSON.parse(attributes.mapStateJSON); + mapState = JSON.parse(attributes.mapStateJSON); } } catch (e) { // ignore malformed mapStateJSON, not a critical error for viewing map - map will just use defaults } - this._initMapAndLayerSettings(serializedMapState); + this._initMapAndLayerSettings(mapState); this.setState({ initialized: true }); } diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts index 1a57c09672c04..2816d4805722c 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts @@ -7,21 +7,21 @@ import { getData } from '../../../kibana_services'; import { MapsAppState } from '../url_state'; -import { SerializedMapState } from './types'; +import { ParsedMapStateJSON } from './types'; export function getInitialQuery({ - serializedMapState, + mapState, appState = {}, }: { - serializedMapState?: SerializedMapState; + mapState?: ParsedMapStateJSON; appState: MapsAppState; }) { if (appState.query) { return appState.query; } - if (serializedMapState?.query) { - return serializedMapState.query; + if (mapState?.query) { + return mapState.query; } return getData().query.queryString.getDefaultQuery(); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts index 79d3603055874..014fa63f10b8b 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts @@ -8,19 +8,19 @@ import { GlobalQueryStateFromUrl } from '@kbn/data-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; import { getUiSettings } from '../../../kibana_services'; -import { SerializedMapState } from './types'; +import { ParsedMapStateJSON } from './types'; export function getInitialRefreshConfig({ - serializedMapState, + mapState, globalState = {}, }: { - serializedMapState?: SerializedMapState; + mapState?: ParsedMapStateJSON; globalState: GlobalQueryStateFromUrl; }) { const uiSettings = getUiSettings(); - if (serializedMapState?.refreshConfig) { - return serializedMapState.refreshConfig; + if (mapState?.refreshConfig) { + return mapState.refreshConfig; } const defaultRefreshConfig = uiSettings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts index 2c09f696a591d..d2d7673aca177 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export type { RefreshConfig, SerializedMapState, SerializedUiState } from './types'; +export type { RefreshConfig, ParsedMapStateJSON, ParsedUiStateJSON } from './types'; export { SavedMap } from './saved_map'; export { getInitialLayersFromUrlParam } from './get_initial_layers_from_url_param'; export { getInitialQuery } from './get_initial_query'; diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index 4b55fa2438714..b1118fcbf00e8 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -53,7 +53,7 @@ import { getBreadcrumbs } from './get_breadcrumbs'; import { DEFAULT_IS_LAYER_TOC_OPEN } from '../../../reducers/ui'; import { createBasemapLayerDescriptor } from '../../../classes/layers/create_basemap_layer_descriptor'; import { whenLicenseInitialized } from '../../../licensed_features'; -import { SerializedMapState, SerializedUiState } from './types'; +import { ParsedMapStateJSON, ParsedUiStateJSON } from './types'; import { setAutoOpenLayerWizardId } from '../../../actions/ui_actions'; import { LayerStatsCollector, MapSettingsCollector } from '../../../../common/telemetry'; import { getIndexPatternsFromIds } from '../../../index_pattern_util'; @@ -150,7 +150,7 @@ export class SavedMap { if (this._attributes?.mapStateJSON) { try { - const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + const mapState = JSON.parse(this._attributes.mapStateJSON) as ParsedMapStateJSON; if (mapState.adHocDataViews && mapState.adHocDataViews.length > 0) { const dataViewService = getIndexPatternService(); const promises = mapState.adHocDataViews.map((spec) => { @@ -167,7 +167,7 @@ export class SavedMap { this._store.dispatch(setMapSettingsFromEncodedState(this._mapEmbeddableInput.mapSettings)); } else if (this._attributes?.mapStateJSON) { try { - const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + const mapState = JSON.parse(this._attributes.mapStateJSON) as ParsedMapStateJSON; if (mapState.settings) { this._store.dispatch(setMapSettingsFromEncodedState(mapState.settings)); } @@ -181,7 +181,7 @@ export class SavedMap { isLayerTOCOpen = this._mapEmbeddableInput.isLayerTOCOpen; } else if (this._attributes?.uiStateJSON) { try { - const uiState = JSON.parse(this._attributes.uiStateJSON) as SerializedUiState; + const uiState = JSON.parse(this._attributes.uiStateJSON) as ParsedUiStateJSON; if ('isLayerTOCOpen' in uiState) { isLayerTOCOpen = uiState.isLayerTOCOpen; } @@ -196,7 +196,7 @@ export class SavedMap { openTOCDetails = this._mapEmbeddableInput.openTOCDetails; } else if (this._attributes?.uiStateJSON) { try { - const uiState = JSON.parse(this._attributes.uiStateJSON) as SerializedUiState; + const uiState = JSON.parse(this._attributes.uiStateJSON) as ParsedUiStateJSON; if ('openTOCDetails' in uiState) { openTOCDetails = uiState.openTOCDetails; } @@ -216,7 +216,7 @@ export class SavedMap { ); } else if (this._attributes?.mapStateJSON) { try { - const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + const mapState = JSON.parse(this._attributes.mapStateJSON) as ParsedMapStateJSON; this._store.dispatch( setGotoWithCenter({ lat: mapState.center.lat, @@ -418,7 +418,7 @@ export class SavedMap { } try { - const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + const mapState = JSON.parse(this._attributes.mapStateJSON) as ParsedMapStateJSON; if (mapState?.settings.autoFitToDataBounds !== undefined) { return mapState.settings.autoFitToDataBounds; } @@ -580,12 +580,12 @@ export class SavedMap { return { ...icon, svg: Buffer.from(icon.svg).toString('base64') }; }), }, - } as SerializedMapState); + } as ParsedMapStateJSON); this._attributes!.uiStateJSON = JSON.stringify({ isLayerTOCOpen: getIsLayerTOCOpen(state), openTOCDetails: getOpenTOCDetails(state), - } as SerializedUiState); + } as ParsedUiStateJSON); } private async _getAdHocDataViews() { diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts index 28568e8610da0..6a8465892071a 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts @@ -16,7 +16,7 @@ export interface RefreshConfig { } // parsed contents of mapStateJSON -export interface SerializedMapState { +export interface ParsedMapStateJSON { adHocDataViews?: DataViewSpec[]; zoom: number; center: MapCenter; @@ -28,7 +28,7 @@ export interface SerializedMapState { } // parsed contents of uiStateJSON -export interface SerializedUiState { +export interface ParsedUiStateJSON { isLayerTOCOpen: boolean; openTOCDetails: string[]; } From 390628d665bda92a4450c586511bf170af3fab7f Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 30 Apr 2024 22:04:10 +0200 Subject: [PATCH 072/104] [SLOs] Disable federated view settings in serverless (#181880) ## Summary Fixes https://github.com/elastic/kibana/issues/181739 Disable federated view settings in serverless !! - [ ] Disabled route and settings page in public - [ ] Uses different put request schema on serverless which doesn't contains remote cluster settings --- .../src/rest_specs/routes/put_settings.ts | 12 ++- .../kbn-slo-schema/src/schema/settings.ts | 2 + .../slo/public/application.tsx | 11 +- .../components/header_menu/header_menu.tsx | 22 ++-- .../slo/public/context/plugin_context.tsx | 1 + .../slo/public/routes/routes.tsx | 102 ++++++++++-------- .../slo/server/plugin.ts | 6 +- .../routes/get_slo_server_route_repository.ts | 10 +- .../slo/server/routes/slo/route.ts | 79 +++++++------- 9 files changed, 142 insertions(+), 103 deletions(-) diff --git a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/put_settings.ts b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/put_settings.ts index ff5e4a1d98051..9bd8b8ca0e95f 100644 --- a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/put_settings.ts +++ b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/put_settings.ts @@ -5,17 +5,25 @@ * 2.0. */ import * as t from 'io-ts'; -import { sloSettingsSchema } from '../../schema/settings'; +import { sloServerlessSettingsSchema, sloSettingsSchema } from '../../schema/settings'; const putSLOSettingsParamsSchema = t.type({ body: sloSettingsSchema, }); +const putSLOServerlessSettingsParamsSchema = t.type({ + body: sloServerlessSettingsSchema, +}); + const putSLOSettingsResponseSchema = sloSettingsSchema; type PutSLOSettingsParams = t.TypeOf; type PutSLOSettingsResponse = t.OutputOf; type GetSLOSettingsResponse = t.OutputOf; -export { putSLOSettingsParamsSchema, putSLOSettingsResponseSchema }; +export { + putSLOSettingsParamsSchema, + putSLOSettingsResponseSchema, + putSLOServerlessSettingsParamsSchema, +}; export type { PutSLOSettingsParams, PutSLOSettingsResponse, GetSLOSettingsResponse }; diff --git a/x-pack/packages/kbn-slo-schema/src/schema/settings.ts b/x-pack/packages/kbn-slo-schema/src/schema/settings.ts index 5eb7e7b23abf3..c4f797e427c48 100644 --- a/x-pack/packages/kbn-slo-schema/src/schema/settings.ts +++ b/x-pack/packages/kbn-slo-schema/src/schema/settings.ts @@ -11,3 +11,5 @@ export const sloSettingsSchema = t.type({ useAllRemoteClusters: t.boolean, selectedRemoteClusters: t.array(t.string), }); + +export const sloServerlessSettingsSchema = t.type({}); diff --git a/x-pack/plugins/observability_solution/slo/public/application.tsx b/x-pack/plugins/observability_solution/slo/public/application.tsx index 7d74467e6868c..9cf739f5e543a 100644 --- a/x-pack/plugins/observability_solution/slo/public/application.tsx +++ b/x-pack/plugins/observability_solution/slo/public/application.tsx @@ -21,18 +21,22 @@ import { Storage } from '@kbn/kibana-utils-plugin/public'; import { ObservabilityRuleTypeRegistry } from '@kbn/observability-plugin/public'; import { i18n } from '@kbn/i18n'; +import { usePluginContext } from './hooks/use_plugin_context'; import { PluginContext } from './context/plugin_context'; import { SloPublicPluginsStart } from './types'; -import { routes } from './routes/routes'; +import { getRoutes } from './routes/routes'; import { ExperimentalFeatures } from '../common/config'; function App() { + const { isServerless } = usePluginContext(); + + const routes = getRoutes(isServerless); + return ( <> - {Object.keys(routes).map((key) => { - const path = key as keyof typeof routes; + {Object.keys(routes).map((path) => { const { handler, exact } = routes[path]; const Wrapper = () => { return handler(); @@ -124,6 +128,7 @@ export const renderApp = ({ - - {i18n.translate('xpack.slo.headerMenu.settings', { - defaultMessage: 'Settings', - })} - + {!isServerless && ( + + {i18n.translate('xpack.slo.headerMenu.settings', { + defaultMessage: 'Settings', + })} + + )}
    diff --git a/x-pack/plugins/observability_solution/slo/public/context/plugin_context.tsx b/x-pack/plugins/observability_solution/slo/public/context/plugin_context.tsx index 13e0158e92055..1f8d6f25e0961 100644 --- a/x-pack/plugins/observability_solution/slo/public/context/plugin_context.tsx +++ b/x-pack/plugins/observability_solution/slo/public/context/plugin_context.tsx @@ -13,6 +13,7 @@ import { ExperimentalFeatures } from '../../common/config'; export interface PluginContextValue { isDev?: boolean; + isServerless?: boolean; appMountParameters?: AppMountParameters; observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry; ObservabilityPageTemplate: React.ComponentType; diff --git a/x-pack/plugins/observability_solution/slo/public/routes/routes.tsx b/x-pack/plugins/observability_solution/slo/public/routes/routes.tsx index 98243caec301e..ebf14ea4a7df0 100644 --- a/x-pack/plugins/observability_solution/slo/public/routes/routes.tsx +++ b/x-pack/plugins/observability_solution/slo/public/routes/routes.tsx @@ -22,54 +22,68 @@ import { import { SlosOutdatedDefinitions } from '../pages/slo_outdated_definitions'; import { SloSettingsPage } from '../pages/slo_settings/slo_settings'; -export const routes = { - [SLOS_PATH]: { - handler: () => { - return ; +export const getRoutes = ( + isServerless?: boolean +): { + [key: string]: { + handler: () => React.ReactElement; + params: Record; + exact: boolean; + }; +} => { + return { + [SLOS_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLO_CREATE_PATH]: { - handler: () => { - return ; + [SLO_CREATE_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLOS_WELCOME_PATH]: { - handler: () => { - return ; + [SLOS_WELCOME_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLOS_OUTDATED_DEFINITIONS_PATH]: { - handler: () => { - return ; + [SLOS_OUTDATED_DEFINITIONS_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLO_EDIT_PATH]: { - handler: () => { - return ; + [SLO_EDIT_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLO_SETTINGS_PATH]: { - handler: () => { - return ; + ...(!isServerless + ? { + [SLO_SETTINGS_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, + }, + } + : {}), + [SLO_DETAIL_PATH]: { + handler: () => { + return ; + }, + params: {}, + exact: true, }, - params: {}, - exact: true, - }, - [SLO_DETAIL_PATH]: { - handler: () => { - return ; - }, - params: {}, - exact: true, - }, + }; }; diff --git a/x-pack/plugins/observability_solution/slo/server/plugin.ts b/x-pack/plugins/observability_solution/slo/server/plugin.ts index b61d0cc200adc..668d7cc6a51be 100644 --- a/x-pack/plugins/observability_solution/slo/server/plugin.ts +++ b/x-pack/plugins/observability_solution/slo/server/plugin.ts @@ -29,6 +29,7 @@ import { SpacesPluginSetup, SpacesPluginStart } from '@kbn/spaces-plugin/server' import { AlertsLocatorDefinition } from '@kbn/observability-plugin/common'; import { SLO_BURN_RATE_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { sloFeatureId } from '@kbn/observability-plugin/common'; +import { ServerlessPluginStart } from '@kbn/serverless/server'; import { registerSloUsageCollector } from './lib/collectors/register'; import { SloOrphanSummaryCleanupTask } from './services/tasks/orphan_summary_cleanup_task'; import { slo, SO_SLO_TYPE } from './saved_objects'; @@ -56,6 +57,7 @@ export interface PluginStart { alerting: PluginStartContract; taskManager: TaskManagerStartContract; spaces?: SpacesPluginStart; + serverless: ServerlessPluginStart; } const sloRuleTypes = [SLO_BURN_RATE_RULE_TYPE_ID]; @@ -150,7 +152,9 @@ export class SloPlugin implements Plugin { getRulesClientWithRequest: pluginStart.alerting.getRulesClientWithRequest, }, logger: this.logger, - repository: getSloServerRouteRepository(config), + repository: getSloServerRouteRepository({ + isServerless: !!pluginStart.serverless, + }), }); const esInternalClient = coreStart.elasticsearch.client.asInternalUser; diff --git a/x-pack/plugins/observability_solution/slo/server/routes/get_slo_server_route_repository.ts b/x-pack/plugins/observability_solution/slo/server/routes/get_slo_server_route_repository.ts index bd062771017fd..b04b6209054a9 100644 --- a/x-pack/plugins/observability_solution/slo/server/routes/get_slo_server_route_repository.ts +++ b/x-pack/plugins/observability_solution/slo/server/routes/get_slo_server_route_repository.ts @@ -5,14 +5,12 @@ * 2.0. */ -import { SloConfig } from '..'; -import { sloRouteRepository } from './slo/route'; +import { getSloRouteRepository } from './slo/route'; -export function getSloServerRouteRepository(config: SloConfig) { - const repository = { - ...sloRouteRepository, +export function getSloServerRouteRepository({ isServerless }: { isServerless?: boolean } = {}) { + return { + ...getSloRouteRepository(isServerless), }; - return repository; } export type SloServerRouteRepository = ReturnType; diff --git a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts index 3d55a9caa3223..1853d09c81f54 100644 --- a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts +++ b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts @@ -21,6 +21,8 @@ import { getSLOInstancesParamsSchema, getSLOParamsSchema, manageSLOParamsSchema, + putSLOServerlessSettingsParamsSchema, + PutSLOSettingsParams, putSLOSettingsParamsSchema, resetSLOParamsSchema, updateSLOParamsSchema, @@ -645,41 +647,44 @@ const getSloSettingsRoute = createSloServerRoute({ }, }); -const putSloSettings = createSloServerRoute({ - endpoint: 'PUT /internal/slo/settings', - options: { - tags: ['access:slo_write'], - access: 'internal', - }, - params: putSLOSettingsParamsSchema, - handler: async ({ context, params }) => { - await assertPlatinumLicense(context); - - const soClient = (await context.core).savedObjects.client; - return await storeSloSettings(soClient, params.body); - }, -}); - -export const sloRouteRepository = { - ...fetchSloHealthRoute, - ...getSloSettingsRoute, - ...putSloSettings, - ...createSLORoute, - ...inspectSLORoute, - ...deleteSLORoute, - ...deleteSloInstancesRoute, - ...disableSLORoute, - ...enableSLORoute, - ...fetchHistoricalSummary, - ...findSloDefinitionsRoute, - ...findSLORoute, - ...getSLORoute, - ...updateSLORoute, - ...getDiagnosisRoute, - ...getSloBurnRates, - ...getPreviewData, - ...getSLOInstancesRoute, - ...resetSLORoute, - ...findSLOGroupsRoute, - ...getSLOSuggestionsRoute, +const putSloSettings = (isServerless?: boolean) => + createSloServerRoute({ + endpoint: 'PUT /internal/slo/settings', + options: { + tags: ['access:slo_write'], + access: 'internal', + }, + params: isServerless ? putSLOServerlessSettingsParamsSchema : putSLOSettingsParamsSchema, + handler: async ({ context, params }) => { + await assertPlatinumLicense(context); + + const soClient = (await context.core).savedObjects.client; + return await storeSloSettings(soClient, params.body as PutSLOSettingsParams); + }, + }); + +export const getSloRouteRepository = (isServerless?: boolean) => { + return { + ...fetchSloHealthRoute, + ...getSloSettingsRoute, + ...putSloSettings(isServerless), + ...createSLORoute, + ...inspectSLORoute, + ...deleteSLORoute, + ...deleteSloInstancesRoute, + ...disableSLORoute, + ...enableSLORoute, + ...fetchHistoricalSummary, + ...findSloDefinitionsRoute, + ...findSLORoute, + ...getSLORoute, + ...updateSLORoute, + ...getDiagnosisRoute, + ...getSloBurnRates, + ...getPreviewData, + ...getSLOInstancesRoute, + ...resetSLORoute, + ...findSLOGroupsRoute, + ...getSLOSuggestionsRoute, + }; }; From a9b4fc8da64c9f612e2912011f12a7b7dae102d2 Mon Sep 17 00:00:00 2001 From: Trevor Pierce <1Copenut@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:17:32 -0500 Subject: [PATCH 073/104] [TASK][Security Serverless]: Add semantic headings to Fleet Integration forms (#181922) Refactored the Fleet "Add Integration" form to properly nest headings by level. --- .../agent_policy_advanced_fields/index.tsx | 44 +++++++++---------- .../components/agent_policy_integration.tsx | 4 +- .../components/package_policy_input_panel.tsx | 7 +-- .../steps/step_define_package_policy.tsx | 4 +- .../single_page_layout/index.tsx | 2 + 5 files changed, 32 insertions(+), 29 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx index 08049f6d81669..b3f3236772ffd 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx @@ -117,12 +117,12 @@ export const AgentPolicyAdvancedOptionsContent: React.FunctionComponent = () => ( +

    -

    + } description={ = <> +

    -

    + } description={ =
    +

    -

    + } description={ =
    +

    -

    + } description={ = +

    = )} -

    + } description={ =
    +

    -

    + } description={ =
    +

    -

    + } description={ =
    +

    -

    + } description={ =
    +

    -

    + } description={ =
    +

    = size="s" /> -

    + } description={ =
    +

      -

    + } description={ = ({ +

    -

    + } description={ - -

    {packageInput.title || packageInput.type}

    -
    + +

    {packageInput.title || packageInput.type}

    +
    } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_define_package_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_define_package_policy.tsx index 289508b516fcc..4f50a0c1cc5f2 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_define_package_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_define_package_policy.tsx @@ -106,12 +106,12 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{ )} +

    -

    + } description={ Date: Tue, 30 Apr 2024 15:36:02 -0500 Subject: [PATCH 074/104] [Security Solution][Alert details] - fix filter in and out not working on user and host expandable flyout opened from timeline (#182174) --- .../entity_details/shared/components/entity_table/columns.tsx | 1 + .../timelines/components/field_renderers/field_renderers.tsx | 3 +++ .../components/timeline/body/renderers/host_name.test.tsx | 2 +- .../timelines/components/timeline/body/renderers/host_name.tsx | 3 +-- .../components/timeline/body/renderers/user_name.test.tsx | 2 +- .../timelines/components/timeline/body/renderers/user_name.tsx | 3 +-- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/entity_table/columns.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/entity_table/columns.tsx index 4466c2e31df46..cda6113ded653 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/entity_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/entity_table/columns.tsx @@ -59,6 +59,7 @@ export const getEntityTableColumns = ( idPrefix={contextID ? `entityTable-${contextID}` : 'entityTable'} isDraggable={isDraggable} sourcererScopeId={getSourcererScopeId(scopeId)} + scopeId={scopeId} render={renderField} data-test-subj="entity-table-value" /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx index 16ab4f04b68d4..afdb79365ff5c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx @@ -201,6 +201,7 @@ interface DefaultFieldRendererProps { render?: (item: string) => React.ReactNode; rowItems: string[] | null | undefined; sourcererScopeId?: SourcererScopeName; + scopeId?: string; } export const DefaultFieldRendererComponent: React.FC = ({ @@ -212,6 +213,7 @@ export const DefaultFieldRendererComponent: React.FC render, rowItems, sourcererScopeId, + scopeId, }) => { if (rowItems != null && rowItems.length > 0) { const draggables = rowItems.slice(0, displayCount).map((rowItem, index) => { @@ -234,6 +236,7 @@ export const DefaultFieldRendererComponent: React.FC value={rowItem} isAggregatable={true} fieldType={'keyword'} + scopeId={scopeId} > {render ? render(rowItem) : rowItem} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx index 1de0eb646eda4..4514409184ba5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx @@ -312,7 +312,7 @@ describe('HostName', () => { params: { hostName: props.value, contextID: props.contextId, - scopeId: TableId.alertsOnAlertsPage, + scopeId: 'timeline-1', isDraggable: false, }, }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx index 705dbcbb0a17c..69e0b34b4b3d3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx @@ -9,7 +9,6 @@ import React, { useCallback, useContext, useMemo } from 'react'; import type { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import { isString } from 'lodash/fp'; -import { TableId } from '@kbn/securitysolution-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; import { HostPanelKey } from '../../../../../flyout/entity_details/host_right'; @@ -81,7 +80,7 @@ const HostNameComponent: React.FC = ({ params: { hostName, contextID: contextId, - scopeId: TableId.alertsOnAlertsPage, + scopeId: timelineID, isDraggable, }, }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx index 6e0edb987f8f2..426839056e51a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx @@ -286,7 +286,7 @@ describe('UserName', () => { params: { userName: props.value, contextID: props.contextId, - scopeId: TableId.alertsOnAlertsPage, + scopeId: 'timeline-1', isDraggable: false, }, }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx index d3f0894346cf8..39069fc7320bb 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx @@ -9,7 +9,6 @@ import React, { useCallback, useContext, useMemo } from 'react'; import type { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import { isString } from 'lodash/fp'; -import { TableId } from '@kbn/securitysolution-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { UserPanelKey } from '../../../../../flyout/entity_details/user_right'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; @@ -79,7 +78,7 @@ const UserNameComponent: React.FC = ({ params: { userName, contextID: contextId, - scopeId: TableId.alertsOnAlertsPage, + scopeId: timelineID, isDraggable, }, }); From 1ca07d87c43ab3703dad9c9a41b29fefff664f62 Mon Sep 17 00:00:00 2001 From: Candace Park <56409205+parkiino@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:39:57 -0400 Subject: [PATCH 075/104] [Security Solution][EDR][Event Filters] Make confirm modal text for wildcard warning more general (#182172) ## Summary - [x] The event filters confirm modal had `Confirm trusted application` instead of 'Confirm event filter' when there is a wildcard with the wrong operator warning present in the entry. # Screenshots BEFORE ![image](https://github.com/elastic/kibana/assets/56409205/fafabb5c-b510-4270-b67e-1c37ca3faf03) AFTER ![image](https://github.com/elastic/kibana/assets/56409205/98430140-17c3-4d63-a4bc-7d553631dba5) --- .../public/management/common/translations.ts | 43 ++++++++++--------- .../event_filters/view/components/form.tsx | 7 ++- .../trusted_apps/view/components/form.tsx | 7 ++- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/common/translations.ts b/x-pack/plugins/security_solution/public/management/common/translations.ts index 5aa3b52e9d7fd..c1d05301afd6c 100644 --- a/x-pack/plugins/security_solution/public/management/common/translations.ts +++ b/x-pack/plugins/security_solution/public/management/common/translations.ts @@ -194,24 +194,27 @@ export const CONSOLE_COMMANDS = { }, }; -export const CONFIRM_WARNING_MODAL_LABELS = { - title: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.title', { - defaultMessage: 'Confirm trusted application', - }), - body: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.body', { - defaultMessage: - 'Using a "*" or a "?" in the value with the "IS" operator can make the entry ineffective. Change the operator to ‘matches’ to ensure wildcards run properly. Select “cancel” to revise your entry, or "add" to continue with the entry in its current state.', - }), - confirmButton: i18n.translate( - 'xpack.securitySolution.artifacts.confirmWarningModal.confirmButtonText', - { - defaultMessage: 'Add', - } - ), - cancelButton: i18n.translate( - 'xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText', - { - defaultMessage: 'Cancel', - } - ), +export const CONFIRM_WARNING_MODAL_LABELS = (entryType: string) => { + return { + title: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.title', { + defaultMessage: `Confirm {type}`, + values: { type: entryType }, + }), + body: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.body', { + defaultMessage: + 'Using a "*" or a "?" in the value with the "IS" operator can make the entry ineffective. Change the operator to ‘matches’ to ensure wildcards run properly. Select “cancel” to revise your entry, or "add" to continue with the entry in its current state.', + }), + confirmButton: i18n.translate( + 'xpack.securitySolution.artifacts.confirmWarningModal.confirmButtonText', + { + defaultMessage: 'Add', + } + ), + cancelButton: i18n.translate( + 'xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText', + { + defaultMessage: 'Cancel', + } + ), + }; }; diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx index d9db594c4e73c..e6d42f65e7a08 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.tsx @@ -19,6 +19,7 @@ import { EuiHorizontalRule, EuiTextArea, } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; @@ -196,7 +197,11 @@ export const EventFiltersForm: React.FC( item: updatedFormValues, isValid: updatedValidationResult.isValid, confirmModalLabels: updatedValidationResult.extraWarning - ? CONFIRM_WARNING_MODAL_LABELS + ? CONFIRM_WARNING_MODAL_LABELS( + i18n.translate('xpack.securitySolution.trustedApps.flyoutForm.confirmModal.name', { + defaultMessage: 'trusted application', + }) + ) : undefined, }); }, From db188e7a360227ae97fd103b84b8f37b88b92cf3 Mon Sep 17 00:00:00 2001 From: Bena Kansara <69037875+benakansara@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:43:15 +0200 Subject: [PATCH 076/104] [APM] [Preview Chart] Fix threshold area annotation and enable tooltip (#181978) Fixes https://github.com/elastic/kibana/issues/159928, https://github.com/elastic/kibana/issues/181148, https://github.com/elastic/sdh-kibana/issues/4596, https://github.com/elastic/kibana/issues/179811 ### Threshold: 0, Y: 0 Screenshot 2024-04-29 at 13 00 39 ### Show empty timestamp if there is no data Screenshot 2024-04-30 at 15 31 58 ### Tooltip Screenshot 2024-04-29 at 14 25 33 --- .../ui_components/chart_preview/index.tsx | 3 +- .../get_error_count_chart_preview.ts | 36 ++++++++--------- .../get_transaction_duration_chart_preview.ts | 40 +++++++++---------- ...et_transaction_error_rate_chart_preview.ts | 36 ++++++++--------- 4 files changed, 57 insertions(+), 58 deletions(-) diff --git a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/index.tsx index 420e26444dbee..8e7cce37b5be4 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/alerting/ui_components/chart_preview/index.tsx @@ -80,7 +80,7 @@ export function ChartPreview({ const { yMin, yMax, xMin, xMax } = getDomain(series); const chartDomain = { - max: Math.max(yMax, threshold) * 1.1, // Add 10% headroom. + max: Math.max(yMax === 0 ? 1 : yMax, threshold) * 1.1, // Add 10% headroom. min: Math.min(yMin, threshold) * 0.9, // Add 10% headroom. }; @@ -110,7 +110,6 @@ export function ChartPreview({ data-test-subj="ChartPreview" > { const dateFormat = (uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts index 682976f9120cb..9366e3f04abbb 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts @@ -63,21 +63,21 @@ export async function getTransactionErrorCountChartPreview({ }; const aggs = { - timeseries: { - date_histogram: { - field: '@timestamp', - fixed_interval: interval, - extended_bounds: { - min: start, - max: end, - }, + series: { + multi_terms: { + terms: getGroupByTerms(allGroupByFields), + size: 1000, + order: { _count: 'desc' as const }, }, aggs: { - series: { - multi_terms: { - terms: getGroupByTerms(allGroupByFields), - size: 1000, - order: { _count: 'desc' as const }, + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: interval, + extended_bounds: { + min: start, + max: end, + }, }, }, }, @@ -95,11 +95,11 @@ export async function getTransactionErrorCountChartPreview({ return { series: [], totalGroups: 0 }; } - const seriesDataMap = resp.aggregations.timeseries.buckets.reduce((acc, bucket) => { - const x = bucket.key; - bucket.series.buckets.forEach((seriesBucket) => { - const bucketKey = seriesBucket.key.join('_'); - const y = seriesBucket.doc_count; + const seriesDataMap = resp.aggregations.series.buckets.reduce((acc, bucket) => { + const bucketKey = bucket.key.join('_'); + bucket.timeseries.buckets.forEach((timeseriesBucket) => { + const x = timeseriesBucket.key; + const y = timeseriesBucket.doc_count; if (acc[bucketKey]) { acc[bucketKey].push({ x, y }); diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts index a13217f4ca136..0dcf1e3255bd7 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts @@ -90,21 +90,21 @@ export async function getTransactionDurationChartPreview({ const allGroupByFields = getAllGroupByFields(ApmRuleType.TransactionDuration, groupByFields); const aggs = { - timeseries: { - date_histogram: { - field: '@timestamp', - fixed_interval: interval, - min_doc_count: 0, - extended_bounds: { - min: start, - max: end, - }, + series: { + multi_terms: { + terms: getGroupByTerms(allGroupByFields), + size: 1000, }, aggs: { - series: { - multi_terms: { - terms: [...getGroupByTerms(allGroupByFields)], - size: 1000, + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: interval, + min_doc_count: 0, + extended_bounds: { + min: start, + max: end, + }, ...getMultiTermsSortOrder(aggregationType), }, aggs: { @@ -130,14 +130,14 @@ export async function getTransactionDurationChartPreview({ return { series: [], totalGroups: 0 }; } - const seriesDataMap = resp.aggregations.timeseries.buckets.reduce((acc, bucket) => { - const x = bucket.key; - bucket.series.buckets.forEach((seriesBucket) => { - const bucketKey = seriesBucket.key.join('_'); + const seriesDataMap = resp.aggregations.series.buckets.reduce((acc, bucket) => { + const bucketKey = bucket.key.join('_'); + bucket.timeseries.buckets.forEach((timeseriesBucket) => { + const x = timeseriesBucket.key; const y = - 'avgLatency' in seriesBucket - ? seriesBucket.avgLatency.value - : seriesBucket.pctLatency.values[0].value; + 'avgLatency' in timeseriesBucket + ? timeseriesBucket.avgLatency.value + : timeseriesBucket.pctLatency.values[0].value; if (acc[bucketKey]) { acc[bucketKey].push({ x, y }); } else { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts index d9f5c11b1cf14..e6fdf321af8d9 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts @@ -97,21 +97,21 @@ export async function getTransactionErrorRateChartPreview({ }, }, aggs: { - timeseries: { - date_histogram: { - field: '@timestamp', - fixed_interval: interval, - extended_bounds: { - min: start, - max: end, - }, + series: { + multi_terms: { + terms: getGroupByTerms(allGroupByFields), + size: 1000, + order: { _count: 'desc' as const }, }, aggs: { - series: { - multi_terms: { - terms: [...getGroupByTerms(allGroupByFields)], - size: 1000, - order: { _count: 'desc' as const }, + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: interval, + extended_bounds: { + min: start, + max: end, + }, }, aggs: { outcomes: { @@ -133,11 +133,11 @@ export async function getTransactionErrorRateChartPreview({ return { series: [], totalGroups: 0 }; } - const seriesDataMap = resp.aggregations.timeseries.buckets.reduce((acc, bucket) => { - const x = bucket.key; - bucket.series.buckets.forEach((seriesBucket) => { - const bucketKey = seriesBucket.key.join('_'); - const y = calculateErrorRate(seriesBucket.outcomes.buckets); + const seriesDataMap = resp.aggregations.series.buckets.reduce((acc, bucket) => { + const bucketKey = bucket.key.join('_'); + bucket.timeseries.buckets.forEach((timeseriesBucket) => { + const x = timeseriesBucket.key; + const y = calculateErrorRate(timeseriesBucket.outcomes.buckets); if (acc[bucketKey]) { acc[bucketKey].push({ x, y }); From 2766ec0f28a891f8e14cf5571f63c9e1212b6655 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 30 Apr 2024 13:47:24 -0700 Subject: [PATCH 077/104] [SharedUX/React render] prevent double-nested EuiProvider (#182005) ## Summary Addresses extraneous errors discovered in https://github.com/elastic/kibana/pull/180819 --------- Co-authored-by: Clint Andrew Hall Co-authored-by: Tiago Costa --- packages/kbn-optimizer/limits.yml | 4 +-- .../kbn-ui-shared-deps-npm/webpack.config.js | 1 + .../kbn-ui-shared-deps-src/src/definitions.js | 2 ++ packages/kbn-ui-shared-deps-src/src/entry.js | 1 + .../kibana_context/root/root_provider.tsx | 31 ++++++++++++++----- .../kibana_context/theme/theme_provider.tsx | 4 +-- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 0cbb1eff71a67..8ee32095e8789 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -31,7 +31,7 @@ pageLoadAssetSize: datasetQuality: 50624 dataViewEditor: 28082 dataViewFieldEditor: 27000 - dataViewManagement: 5176 + dataViewManagement: 5300 dataViews: 65000 dataVisualizer: 27530 devTools: 38637 @@ -51,7 +51,7 @@ pageLoadAssetSize: expressionLegacyMetricVis: 23121 expressionMetric: 22238 expressionMetricVis: 23121 - expressionPartitionVis: 29000 + expressionPartitionVis: 29700 expressionRepeatImage: 22341 expressionRevealImage: 25675 expressions: 140958 diff --git a/packages/kbn-ui-shared-deps-npm/webpack.config.js b/packages/kbn-ui-shared-deps-npm/webpack.config.js index 817a340dc3a8f..79502207aea00 100644 --- a/packages/kbn-ui-shared-deps-npm/webpack.config.js +++ b/packages/kbn-ui-shared-deps-npm/webpack.config.js @@ -60,6 +60,7 @@ module.exports = (_, argv) => { // modules from npm '@elastic/charts', '@elastic/eui', + '@elastic/eui/optimize/es/components/provider/nested', '@elastic/eui/optimize/es/services', '@elastic/eui/optimize/es/services/format', '@elastic/eui/dist/eui_charts_theme', diff --git a/packages/kbn-ui-shared-deps-src/src/definitions.js b/packages/kbn-ui-shared-deps-src/src/definitions.js index 519c706e723fd..78ee1229da4e9 100644 --- a/packages/kbn-ui-shared-deps-src/src/definitions.js +++ b/packages/kbn-ui-shared-deps-src/src/definitions.js @@ -71,6 +71,8 @@ const externals = { '@elastic/charts': '__kbnSharedDeps__.ElasticCharts', '@kbn/datemath': '__kbnSharedDeps__.KbnDatemath', '@elastic/eui': '__kbnSharedDeps__.ElasticEui', + '@elastic/eui/lib/components/provider/nested': + '__kbnSharedDeps__.ElasticEuiLibComponentsUseIsNestedEuiProvider', '@elastic/eui/lib/services': '__kbnSharedDeps__.ElasticEuiLibServices', '@elastic/eui/lib/services/format': '__kbnSharedDeps__.ElasticEuiLibServicesFormat', '@elastic/eui/dist/eui_charts_theme': '__kbnSharedDeps__.ElasticEuiChartsTheme', diff --git a/packages/kbn-ui-shared-deps-src/src/entry.js b/packages/kbn-ui-shared-deps-src/src/entry.js index 1046f2fed7cb2..b012cb5660113 100644 --- a/packages/kbn-ui-shared-deps-src/src/entry.js +++ b/packages/kbn-ui-shared-deps-src/src/entry.js @@ -39,6 +39,7 @@ export const Rxjs = require('rxjs'); export const ElasticNumeral = require('@elastic/numeral'); export const ElasticCharts = require('@elastic/charts'); export const ElasticEui = require('@elastic/eui'); +export const ElasticEuiLibComponentsUseIsNestedEuiProvider = require('@elastic/eui/optimize/es/components/provider/nested'); export const ElasticEuiLibServices = require('@elastic/eui/optimize/es/services'); export const ElasticEuiLibServicesFormat = require('@elastic/eui/optimize/es/services/format'); export const ElasticEuiChartsTheme = require('@elastic/eui/dist/eui_charts_theme'); diff --git a/packages/react/kibana_context/root/root_provider.tsx b/packages/react/kibana_context/root/root_provider.tsx index 19cce446e5f11..f979d0ef49f5d 100644 --- a/packages/react/kibana_context/root/root_provider.tsx +++ b/packages/react/kibana_context/root/root_provider.tsx @@ -6,10 +6,16 @@ * Side Public License, v 1. */ -import type { I18nStart } from '@kbn/core-i18n-browser'; -import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import React, { FC, PropsWithChildren } from 'react'; +import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; +import type { I18nStart } from '@kbn/core-i18n-browser'; + +// @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types +import { useIsNestedEuiProvider } from '@elastic/eui/lib/components/provider/nested'; +// @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types +import { emitEuiProviderWarning } from '@elastic/eui/lib/services/theme/warning'; + import { KibanaEuiProvider, type KibanaEuiProviderProps } from './eui_provider'; /** Props for the KibanaRootContextProvider */ @@ -38,8 +44,19 @@ export const KibanaRootContextProvider: FC ( - - {children} - -); +}) => { + const hasEuiProvider = useIsNestedEuiProvider(); + + if (hasEuiProvider) { + emitEuiProviderWarning( + 'KibanaRootContextProvider has likely been nested in this React tree, either by direct reference or by KibanaRenderContextProvider. The result of this nesting is a nesting of EuiProvider, which has negative effects. Check your React tree for nested Kibana context providers.' + ); + return {children}; + } else { + return ( + + {children} + + ); + } +}; diff --git a/packages/react/kibana_context/theme/theme_provider.tsx b/packages/react/kibana_context/theme/theme_provider.tsx index 1a3bd0f8c1ce2..78b94c1e98793 100644 --- a/packages/react/kibana_context/theme/theme_provider.tsx +++ b/packages/react/kibana_context/theme/theme_provider.tsx @@ -11,9 +11,9 @@ import useObservable from 'react-use/lib/useObservable'; import { EuiThemeProvider, EuiThemeProviderProps } from '@elastic/eui'; -// @ts-ignore EUI exports this component internally, but Kibana isn't picking it up its types +// @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types import { useIsNestedEuiProvider } from '@elastic/eui/lib/components/provider/nested'; -// @ts-ignore EUI exports this component internally, but Kibana isn't picking it up its types +// @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types import { emitEuiProviderWarning } from '@elastic/eui/lib/services/theme/warning'; import { KibanaEuiProvider } from '@kbn/react-kibana-context-root'; From 4c25cb95499c4e4f58baa0194da19b4fe9f17da8 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 30 Apr 2024 17:20:57 -0400 Subject: [PATCH 078/104] [Fleet] Fix add Fleet server scenarios with subfeatures enabled (#182015) --- x-pack/plugins/fleet/common/authz.ts | 16 +++++------ .../cypress/e2e/privileges_editor_role.cy.ts | 27 ++++++++++++++++--- .../plugins/fleet/cypress/tasks/privileges.ts | 5 ++++ .../fleet_server_instructions/index.tsx | 19 ++++++++++--- .../steps/get_started.tsx | 9 ++++++- .../fleet/hooks/use_check_permissions.ts | 9 +++---- .../detail/policies/package_policies.tsx | 16 +++++++++-- .../package_policy_actions_menu.tsx | 10 ++++--- .../plugins/fleet/server/routes/app/index.ts | 18 +++++++++++-- 9 files changed, 101 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/fleet/common/authz.ts b/x-pack/plugins/fleet/common/authz.ts index f6b6673ead2ca..8c5868616e2d4 100644 --- a/x-pack/plugins/fleet/common/authz.ts +++ b/x-pack/plugins/fleet/common/authz.ts @@ -98,6 +98,14 @@ export const calculateAuthz = ({ ? !!(fleet.agents?.all && fleet.agentPolicies?.all && fleet.settings?.all) : fleet.all; + const writeIntegrationPolicies = subfeatureEnabled + ? (fleet.agentPolicies?.all && integrations.all) ?? false + : ((fleet.all || fleet.agentPolicies?.all) ?? false) && integrations.all; + const readIntegrationPolicies = subfeatureEnabled + ? (fleet.agentPolicies?.read && (integrations.all || integrations.read)) ?? false + : ((fleet.all || fleet.read || fleet.agentPolicies?.read) ?? false) && + (integrations.all || integrations.read); + // TODO remove fallback when the feature flag is removed const fleetAuthz: FleetAuthz['fleet'] = subfeatureEnabled ? { @@ -140,14 +148,6 @@ export const calculateAuthz = ({ (fleet.all || fleet.read || fleet.setup || fleet.agentPolicies?.read) ?? false, }; - const writeIntegrationPolicies = subfeatureEnabled - ? (fleet.agentPolicies?.all && integrations.all) ?? false - : ((fleet.all || fleet.agentPolicies?.all) ?? false) && integrations.all; - const readIntegrationPolicies = subfeatureEnabled - ? (fleet.agentPolicies?.read && (integrations.all || integrations.read)) ?? false - : ((fleet.all || fleet.read || fleet.agentPolicies?.read) ?? false) && - (integrations.all || integrations.read); - return { fleet: fleetAuthz, integrations: { diff --git a/x-pack/plugins/fleet/cypress/e2e/privileges_editor_role.cy.ts b/x-pack/plugins/fleet/cypress/e2e/privileges_editor_role.cy.ts index afab363f87ad4..d609379cc5bdd 100644 --- a/x-pack/plugins/fleet/cypress/e2e/privileges_editor_role.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/privileges_editor_role.cy.ts @@ -11,7 +11,7 @@ import { login, loginWithUserAndWaitForPage, logout } from '../tasks/login'; import { getIntegrationCard } from '../screens/integrations'; -import { LANDING_PAGE_ADD_FLEET_SERVER_BUTTON } from '../screens/fleet'; +import { ADD_AGENT_BUTTON, FLEET_SERVER_MISSING_PRIVILEGES } from '../screens/fleet'; import { ADD_INTEGRATION_POLICY_BTN } from '../screens/integrations'; import { scrollToIntegration } from '../tasks/integrations'; @@ -40,9 +40,30 @@ describe('When the user has Editor built-in role', () => { navigateTo(FLEET); }); - it('It should not show a callout', () => { + it('It should not show a callout if fleet server is setup', () => { + cy.intercept('GET', '/api/fleet/agents/setup', { + body: { + isReady: true, + is_secrets_storage_enabled: true, + missing_requirements: [], + missing_optional_features: [], + }, + }); loginWithUserAndWaitForPage(FLEET, BuiltInEditorUser); - cy.getBySel(LANDING_PAGE_ADD_FLEET_SERVER_BUTTON).should('exist'); + cy.getBySel(ADD_AGENT_BUTTON).should('exist'); + }); + + it('It should not show a callout with missing manage_service_accout if fleet server is not setup', () => { + cy.intercept('GET', '/api/fleet/agents/setup', { + body: { + isReady: true, + is_secrets_storage_enabled: true, + missing_requirements: ['fleet_server'], + missing_optional_features: [], + }, + }); + loginWithUserAndWaitForPage(FLEET, BuiltInEditorUser); + cy.getBySel(FLEET_SERVER_MISSING_PRIVILEGES.PROMPT).should('exist'); }); }); diff --git a/x-pack/plugins/fleet/cypress/tasks/privileges.ts b/x-pack/plugins/fleet/cypress/tasks/privileges.ts index 0f8aba10e8fcb..214bd0f14e6e6 100644 --- a/x-pack/plugins/fleet/cypress/tasks/privileges.ts +++ b/x-pack/plugins/fleet/cypress/tasks/privileges.ts @@ -60,6 +60,7 @@ export const FleetAllIntegrAllRole: Role = { privileges: ['all'], }, ], + cluster: ['manage_service_account'], }, kibana: [ { @@ -89,6 +90,7 @@ export const FleetAllIntegrReadRole: Role = { privileges: ['all'], }, ], + cluster: ['manage_service_account'], }, kibana: [ { @@ -116,6 +118,7 @@ export const FleetAllIntegrNoneRole: Role = { privileges: ['all'], }, ], + cluster: ['manage_service_account'], }, kibana: [ { @@ -143,6 +146,7 @@ export const FleetAgentsReadIntegrNoneRole: Role = { privileges: ['all'], }, ], + cluster: ['manage_service_account'], }, kibana: [ { @@ -170,6 +174,7 @@ export const FleetNoneIntegrAllRole: Role = { privileges: ['all'], }, ], + cluster: ['manage_service_account'], }, kibana: [ { diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx index 629fe3c030067..511f5d05154fc 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx @@ -21,10 +21,10 @@ import { EuiButton, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; - import styled from 'styled-components'; -import { useStartServices, useFlyoutContext } from '../../hooks'; +import { useStartServices, useFlyoutContext, useCheckPermissions } from '../../hooks'; +import { FleetServerMissingESPrivileges } from '../../sections/agents/components'; import { QuickStartTab } from './quick_start_tab'; import { AdvancedTab } from './advanced_tab'; @@ -121,6 +121,17 @@ const Header: React.FunctionComponent<{ export const FleetServerFlyout: React.FunctionComponent = ({ onClose }) => { const { tabs, currentTab, setCurrentTab, currentTabContent } = useFleetServerTabs(onClose); + const { permissionsError, isPermissionsLoading } = useCheckPermissions(); + + let errorContent: React.ReactNode | undefined; + if (permissionsError === 'MISSING_FLEET_SERVER_SETUP_PRIVILEGES') { + errorContent = ( + + + + ); + } + return ( @@ -132,7 +143,9 @@ export const FleetServerFlyout: React.FunctionComponent = ({ onClose }) = /> - {currentTabContent} + + {isPermissionsLoading ? null : errorContent ? errorContent : currentTabContent} + ); }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx index 7cb5ae48dbdec..b202bb7bf6cbb 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx @@ -27,7 +27,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { MultiRowInput } from '../../../sections/settings/components/multi_row_input'; -import { useLink } from '../../../hooks'; +import { useAuthz, useLink } from '../../../hooks'; import type { QuickStartCreateForm } from '../hooks'; import { FleetServerHostSelect } from '../components'; @@ -53,6 +53,10 @@ const GettingStartedStepContent: React.FunctionComponent = onClose, }) => { const { getHref } = useLink(); + const authz = useAuthz(); + const canWritePolicies = + authz.fleet.allAgentPolicies && authz.integrations.writeIntegrationPolicies; + const isDisabled = fleetServerHosts.length === 0 && !canWritePolicies; if (status === 'success') { return ( @@ -143,6 +147,7 @@ const GettingStartedStepContent: React.FunctionComponent = defaultMessage: 'Specify name', })} {...inputs.nameInput.props} + disabled={isDisabled} /> = = isLoading={status === 'loading'} onClick={submit} data-test-subj="generateFleetServerPolicyButton" + disabled={isDisabled} > {fleetServerHosts.length > 0 ? ( { - const { data: permissionsError, status } = useQuery( - ['fetch-check-permissions'], - checkPermissions - ); - return { isPermissionsLoading: status === 'loading', permissionsError }; + const { data, isInitialLoading } = useQuery(['fetch-check-permissions'], checkPermissions); + return { isPermissionsLoading: isInitialLoading, permissionsError: data?.error }; }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx index 9b42fdd42f10c..be59e2d64f15c 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx @@ -20,6 +20,8 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedRelative, FormattedMessage } from '@kbn/i18n-react'; +import { policyHasFleetServer } from '../../../../../../../../common/services'; + import { InstallStatus } from '../../../../../types'; import type { GetAgentPoliciesResponseItem, InMemoryPackagePolicy } from '../../../../../types'; import { @@ -113,6 +115,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies; const canAddAgents = useAuthz().fleet.addAgents; + const canAddFleetServers = useAuthz().fleet.addFleetServers; const packageAndAgentPolicies = useMemo((): Array<{ agentPolicy?: GetAgentPoliciesResponseItem; @@ -264,12 +267,15 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps if (!agentPolicy) { return null; } + const canAddAgentsForPolicy = policyHasFleetServer(agentPolicy) + ? canAddFleetServers + : canAddAgents; return ( setFlyoutOpenForPolicyId(agentPolicy.id)} - canAddAgents={canAddAgents} + canAddAgents={canAddAgentsForPolicy} hasHelpPopover={showAddAgentHelpForPackagePolicyId === packagePolicy.id} /> ); @@ -301,7 +307,13 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps }, }, ], - [getHref, canWriteIntegrationPolicies, canAddAgents, showAddAgentHelpForPackagePolicyId] + [ + getHref, + canWriteIntegrationPolicies, + canAddAgents, + canAddFleetServers, + showAddAgentHelpForPackagePolicyId, + ] ); const noItemsMessage = useMemo(() => { diff --git a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx index e7f54fc1b8c54..23ae673ad892a 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx @@ -10,8 +10,8 @@ import { EuiContextMenuItem, EuiPortal } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { AgentPolicy, InMemoryPackagePolicy } from '../types'; - import { useAgentPolicyRefresh, useAuthz, useLink } from '../hooks'; +import { policyHasFleetServer } from '../services'; import { AgentEnrollmentFlyout } from './agent_enrollment_flyout'; import { ContextMenuActions } from './context_menu_actions'; @@ -35,8 +35,12 @@ export const PackagePolicyActionsMenu: React.FunctionComponent<{ }) => { const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); const { getHref } = useLink(); - const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies; - const canAddAgents = useAuthz().fleet.addAgents; + const authz = useAuthz(); + + const canWriteIntegrationPolicies = authz.integrations.writeIntegrationPolicies; + const isFleetServerPolicy = agentPolicy && policyHasFleetServer(agentPolicy); + + const canAddAgents = isFleetServerPolicy ? authz.fleet.addFleetServers : authz.fleet.addAgents; const refreshAgentPolicy = useAgentPolicyRefresh(); const [isActionsMenuOpen, setIsActionsMenuOpen] = useState(defaultIsOpen); diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index 765684a9adbe4..262bdc867df35 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -47,6 +47,20 @@ export const getCheckPermissionsHandler: FleetRequestHandler< error: 'MISSING_PRIVILEGES', } as CheckPermissionsResponse, }); + } else if (request.query.fleetServerSetup) { + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const { has_all_requested: hasAllPrivileges } = await esClient.security.hasPrivileges({ + body: { cluster: ['manage_service_account'] }, + }); + + if (!hasAllPrivileges) { + return response.ok({ + body: { + success: false, + error: 'MISSING_FLEET_SERVER_SETUP_PRIVILEGES', + } as CheckPermissionsResponse, + }); + } } return response.ok({ body: { success: true } as CheckPermissionsResponse }); @@ -142,7 +156,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => { .post({ path: APP_API_ROUTES.GENERATE_SERVICE_TOKEN_PATTERN, fleetAuthz: { - fleet: { all: true }, + fleet: { allAgents: true }, }, }) .addVersion( @@ -159,7 +173,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => { .post({ path: APP_API_ROUTES.GENERATE_SERVICE_TOKEN_PATTERN_DEPRECATED, fleetAuthz: { - fleet: { all: true }, + fleet: { allAgents: true }, }, }) .addVersion( From 9ad7382c95baa6548a779f582b285fcb932ea1fa Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 30 Apr 2024 14:40:10 -0700 Subject: [PATCH 079/104] [Saved objects tagging] Sort response data for test stability (#181366) ## Summary Update test code that compares the tags received from a remote call, to address test flakiness. Addresses https://github.com/elastic/kibana/issues/180117 Closes https://github.com/elastic/kibana/issues/181307 --- .../security_and_spaces/apis/get_all.ts | 44 +++++++++++-------- .../functional/tests/discover_integration.ts | 2 + 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/x-pack/test/saved_object_tagging/api_integration/security_and_spaces/apis/get_all.ts b/x-pack/test/saved_object_tagging/api_integration/security_and_spaces/apis/get_all.ts index e200056795616..124fcea644c79 100644 --- a/x-pack/test/saved_object_tagging/api_integration/security_and_spaces/apis/get_all.ts +++ b/x-pack/test/saved_object_tagging/api_integration/security_and_spaces/apis/get_all.ts @@ -35,24 +35,32 @@ export default function (ftrContext: FtrProviderContext) { authorized: { httpCode: 200, expectResponse: ({ body }) => { - expect(body).to.eql({ - tags: [ - { - id: 'default-space-tag-1', - name: 'tag-1', - description: 'Tag 1 in default space', - color: '#FF00FF', - managed: false, - }, - { - id: 'default-space-tag-2', - name: 'tag-2', - description: 'Tag 2 in default space', - color: '#77CC11', - managed: false, - }, - ], - }); + if (!Array.isArray(body.tags)) { + throw new Error('Expected body.tags to be an array'); + } + + const tags = (body.tags as [{ id: string }]) + // sort the tags by ID alphabetically + .sort((a, b) => { + return a.id.localeCompare(b.id); + }); + + expect(tags).to.eql([ + { + id: 'default-space-tag-1', + name: 'tag-1', + description: 'Tag 1 in default space', + color: '#FF00FF', + managed: false, + }, + { + id: 'default-space-tag-2', + name: 'tag-2', + description: 'Tag 2 in default space', + color: '#77CC11', + managed: false, + }, + ]); }, }, unauthorized: { diff --git a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts index 8258b4570ed9b..365ce9a715816 100644 --- a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts +++ b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts @@ -48,6 +48,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const searchTitles = await Promise.all( searchTitleWrappers.map((entry) => entry.getVisibleText()) ); + searchTitles.sort(); + savedSearchTitles.sort(); expect(searchTitles).to.eql(savedSearchTitles); }); }; From 571c7cafb5d389e99fd2d22887fd1b9a2257a644 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 30 Apr 2024 16:15:41 -0600 Subject: [PATCH 080/104] [Embeddable Rebuild] Add `HasAppContext` interface (#181628) Closes https://github.com/elastic/kibana/issues/182189 ## Summary This PR adds a `HasAppContext` interface that can be used by embeddables that have an editor app, as described [here](https://github.com/elastic/kibana/issues/181484#issuecomment-2086666155). It also makes the `onEdit` and `getEditHref` methods **async** for all embeddables - the reason for why is explained [here](https://github.com/elastic/kibana/pull/181628#discussion_r1583233074). ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../presentation_publishing/index.ts | 5 ++++ .../interfaces/has_app_context.ts | 26 +++++++++++++++++++ .../interfaces/has_edit_capabilities.ts | 4 +-- .../dashboard_container_factory.tsx | 2 +- src/plugins/embeddable/public/index.ts | 1 - .../edit_legacy_embeddable.test.tsx | 2 +- .../public/lib/embeddables/embeddable.tsx | 4 +-- .../public/lib/embeddables/i_embeddable.ts | 9 +------ .../public/lib/embeddables/index.ts | 7 +---- .../public/lib/state_transfer/types.ts | 7 ++--- .../edit_panel_action/edit_panel_action.ts | 4 +-- .../renderers/embeddable/embeddable.tsx | 2 +- 12 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 packages/presentation/presentation_publishing/interfaces/has_app_context.ts diff --git a/packages/presentation/presentation_publishing/index.ts b/packages/presentation/presentation_publishing/index.ts index 720663374cf72..52027ffe90839 100644 --- a/packages/presentation/presentation_publishing/index.ts +++ b/packages/presentation/presentation_publishing/index.ts @@ -43,6 +43,11 @@ export { type PublishesUnifiedSearch, type PublishesWritableUnifiedSearch, } from './interfaces/fetch/publishes_unified_search'; +export { + apiHasAppContext, + type HasAppContext, + type EmbeddableAppContext, +} from './interfaces/has_app_context'; export { apiHasDisableTriggers, type HasDisableTriggers } from './interfaces/has_disable_triggers'; export { hasEditCapabilities, type HasEditCapabilities } from './interfaces/has_edit_capabilities'; export { diff --git a/packages/presentation/presentation_publishing/interfaces/has_app_context.ts b/packages/presentation/presentation_publishing/interfaces/has_app_context.ts new file mode 100644 index 0000000000000..e5ee43f0e7630 --- /dev/null +++ b/packages/presentation/presentation_publishing/interfaces/has_app_context.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export interface EmbeddableAppContext { + /** + * Current app's path including query and hash starting from {appId} + */ + getCurrentPath?: () => string; + currentAppId: string; +} + +export interface HasAppContext { + getAppContext: () => EmbeddableAppContext; +} + +export const apiHasAppContext = (unknownApi: unknown): unknownApi is HasAppContext => { + return ( + (unknownApi as HasAppContext).getAppContext !== undefined && + typeof (unknownApi as HasAppContext).getAppContext === 'function' + ); +}; diff --git a/packages/presentation/presentation_publishing/interfaces/has_edit_capabilities.ts b/packages/presentation/presentation_publishing/interfaces/has_edit_capabilities.ts index 24ce82529419c..b404b6afa0d97 100644 --- a/packages/presentation/presentation_publishing/interfaces/has_edit_capabilities.ts +++ b/packages/presentation/presentation_publishing/interfaces/has_edit_capabilities.ts @@ -15,9 +15,9 @@ import { HasTypeDisplayName } from './has_type'; * edited, and an isEditingEnabled function. */ export interface HasEditCapabilities extends HasTypeDisplayName { - onEdit: () => void; + onEdit: () => Promise; isEditingEnabled: () => boolean; - getEditHref?: () => string | undefined; + getEditHref?: () => Promise; } /** diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container_factory.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container_factory.tsx index c7bcc14ef6b25..6944edb5afa7a 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container_factory.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container_factory.tsx @@ -14,13 +14,13 @@ import { EmbeddablePersistableStateService } from '@kbn/embeddable-plugin/common import { Container, ContainerOutput, - EmbeddableAppContext, EmbeddableFactory, EmbeddableFactoryDefinition, EmbeddablePackageState, ErrorEmbeddable, } from '@kbn/embeddable-plugin/public'; import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; +import { EmbeddableAppContext } from '@kbn/presentation-publishing'; import { DASHBOARD_CONTAINER_TYPE } from '..'; import { createExtract, createInject, DashboardContainerInput } from '../../../common'; diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index 083fd9e774ce9..0a943736d0a75 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -62,7 +62,6 @@ export type { ChartActionContext, ContainerInput, ContainerOutput, - EmbeddableAppContext, EmbeddableContainerSettings, EmbeddableContext, EmbeddableEditorState, diff --git a/src/plugins/embeddable/public/lib/embeddables/compatibility/edit_legacy_embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/compatibility/edit_legacy_embeddable.test.tsx index fdceeda6dd60f..11c7c6683f39c 100644 --- a/src/plugins/embeddable/public/lib/embeddables/compatibility/edit_legacy_embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/compatibility/edit_legacy_embeddable.test.tsx @@ -84,7 +84,7 @@ test('canEditEmbeddable returns false when edit url is available, in edit mode, test('getEditHref returns the edit url', async () => { const embeddable = new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true); - expect(embeddable.getEditHref()).toBe(embeddable.getOutput().editUrl); + expect(await embeddable.getEditHref()).toBe(embeddable.getOutput().editUrl); }); test('redirects to app using state transfer', async () => { diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index 07c52f6cbeed1..fb6a093d54817 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -12,10 +12,10 @@ import * as Rx from 'rxjs'; import { merge } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, skip } from 'rxjs'; import { RenderCompleteDispatcher } from '@kbn/kibana-utils-plugin/public'; +import { EmbeddableAppContext } from '@kbn/presentation-publishing'; import { Adapters } from '../types'; import { IContainer } from '../containers'; import { - EmbeddableAppContext, EmbeddableError, EmbeddableOutput, IEmbeddable, @@ -189,7 +189,7 @@ export abstract class Embeddable< public isCompatibleWithUnifiedSearch: LegacyEmbeddableAPI['isCompatibleWithUnifiedSearch']; public savedObjectId: LegacyEmbeddableAPI['savedObjectId']; - public getEditHref(): string | undefined { + public async getEditHref(): Promise { return this.getOutput().editUrl ?? undefined; } diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 050e18c2442c5..2c4131abd824d 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -25,6 +25,7 @@ import { PublishesPhaseEvents, PublishesSavedObjectId, HasLegacyLibraryTransforms, + EmbeddableAppContext, } from '@kbn/presentation-publishing'; import { Observable } from 'rxjs'; import { EmbeddableInput } from '../../../common/types'; @@ -58,14 +59,6 @@ export type LegacyEmbeddableAPI = HasType & EmbeddableHasTimeRange & PublishesSavedObjectId; -export interface EmbeddableAppContext { - /** - * Current app's path including query and hash starting from {appId} - */ - getCurrentPath?: () => string; - currentAppId?: string; -} - export interface EmbeddableOutput { // Whether the embeddable is actively loading. loading?: boolean; diff --git a/src/plugins/embeddable/public/lib/embeddables/index.ts b/src/plugins/embeddable/public/lib/embeddables/index.ts index cf4637d46915c..e65f8b2f61001 100644 --- a/src/plugins/embeddable/public/lib/embeddables/index.ts +++ b/src/plugins/embeddable/public/lib/embeddables/index.ts @@ -19,10 +19,5 @@ export { EmbeddableRoot } from './embeddable_root'; export { ErrorEmbeddable } from './error_embeddable'; export { isErrorEmbeddable } from './is_error_embeddable'; export { isEmbeddable } from './is_embeddable'; -export type { - EmbeddableAppContext, - EmbeddableInput, - EmbeddableOutput, - IEmbeddable, -} from './i_embeddable'; +export type { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable'; export { withEmbeddableSubscription } from './with_subscription'; diff --git a/src/plugins/embeddable/public/lib/state_transfer/types.ts b/src/plugins/embeddable/public/lib/state_transfer/types.ts index db6085f6ea276..cc9e2e0ee8ef6 100644 --- a/src/plugins/embeddable/public/lib/state_transfer/types.ts +++ b/src/plugins/embeddable/public/lib/state_transfer/types.ts @@ -6,9 +6,6 @@ * Side Public License, v 1. */ -import { Optional } from '@kbn/utility-types'; -import { EmbeddableInput, SavedObjectEmbeddableInput } from '..'; - export const EMBEDDABLE_EDITOR_STATE_KEY = 'embeddable_editor_state'; /** @@ -19,7 +16,7 @@ export interface EmbeddableEditorState { originatingApp: string; originatingPath?: string; embeddableId?: string; - valueInput?: EmbeddableInput; + valueInput?: unknown; /** * Pass current search session id when navigating to an editor, @@ -40,7 +37,7 @@ export const EMBEDDABLE_PACKAGE_STATE_KEY = 'embeddable_package_state'; */ export interface EmbeddablePackageState { type: string; - input: Optional | Optional; + input: unknown; embeddableId?: string; size?: { width?: number; diff --git a/src/plugins/presentation_panel/public/panel_actions/edit_panel_action/edit_panel_action.ts b/src/plugins/presentation_panel/public/panel_actions/edit_panel_action/edit_panel_action.ts index a8d0f12ab4bec..bf19e73d829fd 100644 --- a/src/plugins/presentation_panel/public/panel_actions/edit_panel_action/edit_panel_action.ts +++ b/src/plugins/presentation_panel/public/panel_actions/edit_panel_action/edit_panel_action.ts @@ -74,7 +74,7 @@ export class EditPanelAction public async getHref({ embeddable }: EmbeddableApiContext): Promise { if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); - return embeddable?.getEditHref?.(); + return await embeddable?.getEditHref?.(); } public async isCompatible({ embeddable }: EmbeddableApiContext) { @@ -84,6 +84,6 @@ export class EditPanelAction public async execute({ embeddable }: EmbeddableApiContext) { if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); - embeddable.onEdit(); + await embeddable.onEdit(); } } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index 9e468d1702e92..f1e0387c3a5d6 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -6,7 +6,6 @@ */ import { CoreStart } from '@kbn/core/public'; -import type { EmbeddableAppContext } from '@kbn/embeddable-plugin/public'; import { EmbeddableFactory, EmbeddableFactoryNotFoundError, @@ -17,6 +16,7 @@ import { ReactEmbeddableRenderer, } from '@kbn/embeddable-plugin/public'; import { PresentationContainer } from '@kbn/presentation-containers'; +import { EmbeddableAppContext } from '@kbn/presentation-publishing'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import React, { FC } from 'react'; import ReactDOM from 'react-dom'; From f39b200a8645cd38beee9ba2101dd7f6caa81a33 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 03:47:58 +0100 Subject: [PATCH 081/104] skip flaky suite (#182206) --- .../e2e/investigations/alerts/changing_alert_status.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts index bb5d45654e287..fe8a63efb1102 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts @@ -40,7 +40,8 @@ import { visit } from '../../../tasks/navigation'; import { ALERTS_URL } from '../../../urls/navigation'; // Iusse tracked in: https://github.com/elastic/kibana/issues/167809 -describe('Changing alert status', { tags: ['@ess', '@skipInServerless'] }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/182206 +describe.skip('Changing alert status', { tags: ['@ess', '@skipInServerless'] }, () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'auditbeat_multiple' }); }); From 9cadd20d5e64955d9de50d004b64977b835d13e7 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 03:51:50 +0100 Subject: [PATCH 082/104] fix(NA): missing types --- .../visualize_app/components/visualize_byvalue_editor.tsx | 2 +- .../public/visualize_app/components/visualize_editor.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx index 8cc220e77c8bc..5016b7c301bb4 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx @@ -46,7 +46,7 @@ export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { setOriginatingPath(pathValue); setOriginatingApp(value); - setValueInput(valueInputValue); + setValueInput(valueInputValue as any); setEmbeddableId(embeddableIdValue); if (!valueInputValue) { diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index 70c0c111ce581..5bd36f7097c76 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -52,7 +52,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { } else { data.search.session.start(); } - setEmbeddableInput(valueInputValue); + setEmbeddableInput(valueInputValue as any); setEmbeddableId(embeddableId); setOriginatingApp(value); setOriginatingPath(pathValue); From 088e70d00ea035369f15cecc30ceb0779747efe8 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 03:53:31 +0100 Subject: [PATCH 083/104] skip flaky suite (#173666) --- .../functional_with_es_ssl/apps/triggers_actions_ui/details.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index a6b5af188c260..3aee927ffcfd2 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -987,7 +987,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('Execution log', () => { + // FLAKY: https://github.com/elastic/kibana/issues/173666 + describe.skip('Execution log', () => { const testRunUuid = uuidv4(); let rule: any; From 085d2368b08df645966a450025e297524682da4a Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 1 May 2024 07:04:29 +0200 Subject: [PATCH 084/104] [Lens] Fix table sorting on time picker interval change (#182173) ## Summary Fixes #182153 Due to some specific implementation of the schema sorting in the EUI datagrid, sometimes the table row can be `null/undefined` and the comparison function utility wasn't prepared for that. Now the utility is resilient to `null` rows. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- packages/kbn-sort-predicates/README.md | 1 + .../kbn-sort-predicates/src/sorting.test.ts | 54 ++++++++++++++++++- packages/kbn-sort-predicates/src/sorting.ts | 46 ++++++++++------ 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/packages/kbn-sort-predicates/README.md b/packages/kbn-sort-predicates/README.md index bc1a2fa86b028..b2e3e07b8ff75 100644 --- a/packages/kbn-sort-predicates/README.md +++ b/packages/kbn-sort-predicates/README.md @@ -9,6 +9,7 @@ This package contains a flexible sorting function who supports the following typ * dates (both as number or ISO string) * ranges open and closed (number type only for now) * null and undefined (always sorted as last entries, no matter the direction) + * if it matters the difference: null values are sorted always before undefined ones * any multi-value version of the types above (version excluded) * for multi-values with different length it wins the first non-zero comparison (see note at the bottom) diff --git a/packages/kbn-sort-predicates/src/sorting.test.ts b/packages/kbn-sort-predicates/src/sorting.test.ts index e2fd1a9448c58..12a3c815d2412 100644 --- a/packages/kbn-sort-predicates/src/sorting.test.ts +++ b/packages/kbn-sort-predicates/src/sorting.test.ts @@ -46,6 +46,56 @@ function testSorting({ } describe('Data sorting criteria', () => { + describe('null rows', () => { + // in these tests it needs to skip the testSorting utility in order to pass null rows + // mind that [].sort() will never pass `undefined` values to the comparison function + // so we test it with null values instead + it('should not crash with null rows with strings', () => { + const datatable = ['a', 'b', 'c', 'd', '12']; + const datatableWithNulls = datatable.flatMap((v) => [{ a: v }, null]); + const criteria = getSortingCriteria('string', 'a', getMockFormatter()); + expect( + datatableWithNulls + .sort((a, b) => criteria(a, b, 'asc')) + .map((row) => (row == null ? row : row.a)) + ).toEqual(['12', 'a', 'b', 'c', 'd', ...Array(datatable.length).fill(null)]); + expect( + datatableWithNulls + .sort((a, b) => criteria(a, b, 'desc')) + .map((row) => (row == null ? row : row.a)) + ).toEqual(['d', 'c', 'b', 'a', '12', ...Array(datatable.length).fill(null)]); + }); + + it('should not crash with null rows with version', () => { + const datatable = ['1.21.0', '1.1.0', '1.112.0', '1.0.0', '__other__']; + const datatableWithNulls = datatable.flatMap((v) => [{ a: v }, null]); + const criteria = getSortingCriteria('version', 'a', getMockFormatter()); + expect( + datatableWithNulls + .sort((a, b) => criteria(a, b, 'asc')) + .map((row) => (row == null ? row : row.a)) + ).toEqual([ + '1.0.0', + '1.1.0', + '1.21.0', + '1.112.0', + ...Array(datatable.length).fill(null), + '__other__', + ]); + expect( + datatableWithNulls + .sort((a, b) => criteria(a, b, 'desc')) + .map((row) => (row == null ? row : row.a)) + ).toEqual([ + '1.112.0', + '1.21.0', + '1.1.0', + '1.0.0', + ...Array(datatable.length).fill(null), + '__other__', + ]); + }); + }); describe('Date values', () => { for (const direction of ['asc', 'desc'] as const) { it(`should provide the date criteria for date values (${direction})`, () => { @@ -229,7 +279,7 @@ describe('Data sorting criteria', () => { it('should sort non-version stuff to the end', () => { testSorting({ input: ['1.21.0', undefined, '1.1.0', null, '1.112.0', '__other__', '1.0.0'], - output: ['1.0.0', '1.1.0', '1.21.0', '1.112.0', undefined, null, '__other__'], + output: ['1.0.0', '1.1.0', '1.21.0', '1.112.0', null, undefined, '__other__'], direction: 'asc', type: 'version', reverseOutput: false, @@ -237,7 +287,7 @@ describe('Data sorting criteria', () => { testSorting({ input: ['1.21.0', undefined, '1.1.0', null, '1.112.0', '__other__', '1.0.0'], - output: ['1.112.0', '1.21.0', '1.1.0', '1.0.0', undefined, null, '__other__'], + output: ['1.112.0', '1.21.0', '1.1.0', '1.0.0', null, undefined, '__other__'], direction: 'desc', type: 'version', reverseOutput: false, diff --git a/packages/kbn-sort-predicates/src/sorting.ts b/packages/kbn-sort-predicates/src/sorting.ts index e9fed6e5cfc0d..e9b2c1acb9fe6 100644 --- a/packages/kbn-sort-predicates/src/sorting.ts +++ b/packages/kbn-sort-predicates/src/sorting.ts @@ -133,11 +133,17 @@ function getSafeIpAddress(ip: string | undefined, directionFactor: number) { } const versionComparison: CompareFn = (v1, v2, direction) => { - const valueA = String(v1 ?? ''); - const valueB = String(v2 ?? ''); + const valueA = String(v1 == null ? '' : v1); + const valueB = String(v2 == null ? '' : v2); const aInvalid = !valueA || !valid(valueA); const bInvalid = !valueB || !valid(valueB); if (aInvalid && bInvalid) { + if (v1 == null && v1 !== v2) { + return direction * -1; + } + if (v2 == null && v1 !== v2) { + return direction * 1; + } return 0; } // need to fight the direction multiplication of the parent function @@ -164,30 +170,32 @@ const rangeComparison: CompareFn> = (v1, v2) => { function createArrayValuesHandler(sortBy: string, formatter: FieldFormat) { return function (criteriaFn: CompareFn) { return ( - rowA: Record, - rowB: Record, + rowA: Record | undefined | null, + rowB: Record | undefined | null, direction: 'asc' | 'desc' ) => { // handle the direction with a multiply factor. const directionFactor = direction === 'asc' ? 1 : -1; + // make it handle null/undefined values + // this masks null/undefined rows into null/undefined values so it can benefit from shared invalid logic + // and enable custom sorting for invalid values (like for version type) + const valueA = rowA == null ? rowA : rowA[sortBy]; + const valueB = rowB == null ? rowB : rowB[sortBy]; // if either side of the comparison is an array, make it also the other one become one // then perform an array comparison - if (Array.isArray(rowA[sortBy]) || Array.isArray(rowB[sortBy])) { + if (Array.isArray(valueA) || Array.isArray(valueB)) { return ( directionFactor * compareArrays( - (Array.isArray(rowA[sortBy]) ? rowA[sortBy] : [rowA[sortBy]]) as T[], - (Array.isArray(rowB[sortBy]) ? rowB[sortBy] : [rowB[sortBy]]) as T[], + (Array.isArray(valueA) ? valueA : [valueA]) as T[], + (Array.isArray(valueB) ? valueB : [valueB]) as T[], directionFactor, formatter, criteriaFn ) ); } - return ( - directionFactor * - criteriaFn(rowA[sortBy] as T, rowB[sortBy] as T, directionFactor, formatter) - ); + return directionFactor * criteriaFn(valueA as T, valueB as T, directionFactor, formatter); }; }; } @@ -201,12 +209,12 @@ function getUndefinedHandler( ) => number ) { return ( - rowA: Record, - rowB: Record, + rowA: Record | undefined | null, + rowB: Record | undefined | null, direction: 'asc' | 'desc' ) => { - const valueA = rowA[sortBy]; - const valueB = rowB[sortBy]; + const valueA = rowA?.[sortBy]; + const valueB = rowB?.[sortBy]; // do not use the utility above as null at root level is handled differently // than null/undefined within an array type if (valueA == null || Number.isNaN(valueA)) { @@ -218,7 +226,7 @@ function getUndefinedHandler( if (valueB == null || Number.isNaN(valueB)) { return -1; } - return sortingCriteria(rowA, rowB, direction); + return sortingCriteria(rowA!, rowB!, direction); }; } @@ -226,7 +234,11 @@ export function getSortingCriteria( type: string | undefined, sortBy: string, formatter: FieldFormat -) { +): ( + rowA: Record | undefined | null, + rowB: Record | undefined | null, + direction: 'asc' | 'desc' +) => number { const arrayValueHandler = createArrayValuesHandler(sortBy, formatter); if (type === 'date') { From 6aab9948b836346b1bb7c843cd95f773e0ab43b4 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 1 May 2024 07:55:24 +0200 Subject: [PATCH 085/104] Config: add support for `${VAR:default}` syntax (#182139) ## Summary Fix https://github.com/elastic/kibana/issues/100854 ### Release note The Kibana configuration file now supports assigning default value for environment variables, using the `${VAR_ENV:defaultValue}` syntax. --- docs/setup/settings.asciidoc | 7 +++- .../src/__fixtures__/en_var_with_defaults.yml | 4 ++ .../kbn-config/src/raw/read_config.test.ts | 23 +++++++++++ packages/kbn-config/src/raw/read_config.ts | 13 +------ packages/kbn-config/src/raw/utils.test.ts | 38 ++++++++++++++++++- packages/kbn-config/src/raw/utils.ts | 22 +++++++++++ 6 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 packages/kbn-config/src/__fixtures__/en_var_with_defaults.yml diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 9d5cedff34c84..a1f0a4ebed8a4 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -14,8 +14,11 @@ KBN_PATH_CONF=/home/kibana/config ./bin/kibana -- The default host and port settings configure {kib} to run on `localhost:5601`. To change this behavior and allow remote users to connect, you'll need to update your `kibana.yml` file. You can also enable SSL and set a -variety of other options. Finally, environment variables can be injected into -configuration using `${MY_ENV_VAR}` syntax. +variety of other options. + +Environment variables can be injected into configuration using `${MY_ENV_VAR}` syntax. By default, configuration validation +will fail if an environment variable used in the config file is not present when Kibana starts. This behavior can be changed by using a default value +for the environment variable, using the `${MY_ENV_VAR:defaultValue}` syntax. `console.ui.enabled`:: Toggling this causes the server to regenerate assets on the next startup, diff --git a/packages/kbn-config/src/__fixtures__/en_var_with_defaults.yml b/packages/kbn-config/src/__fixtures__/en_var_with_defaults.yml new file mode 100644 index 0000000000000..250f863ff4ff6 --- /dev/null +++ b/packages/kbn-config/src/__fixtures__/en_var_with_defaults.yml @@ -0,0 +1,4 @@ +foo: 'pre-${KBN_ENV_VAR1}-mid-${KBN_ENV_VAR2:default2}-post' +nested_list: + - id: 'a' + values: ['${KBN_ENV_VAR1:default1}', '${KBN_ENV_VAR2:default2}'] diff --git a/packages/kbn-config/src/raw/read_config.test.ts b/packages/kbn-config/src/raw/read_config.test.ts index 750d10940e5ce..4a3754def8ae7 100644 --- a/packages/kbn-config/src/raw/read_config.test.ts +++ b/packages/kbn-config/src/raw/read_config.test.ts @@ -130,3 +130,26 @@ test('supports unsplittable key syntax on nested list', () => { } `); }); + +test('supports var:default syntax', () => { + process.env.KBN_ENV_VAR1 = 'val1'; + + const config = getConfigFromFiles([fixtureFile('/en_var_with_defaults.yml')]); + + delete process.env.KBN_ENV_VAR1; + + expect(config).toMatchInlineSnapshot(` + Object { + "foo": "pre-val1-mid-default2-post", + "nested_list": Array [ + Object { + "id": "a", + "values": Array [ + "val1", + "default2", + ], + }, + ], + } + `); +}); diff --git a/packages/kbn-config/src/raw/read_config.ts b/packages/kbn-config/src/raw/read_config.ts index 52ffcaa1bd190..1126ac1bc3f81 100644 --- a/packages/kbn-config/src/raw/read_config.ts +++ b/packages/kbn-config/src/raw/read_config.ts @@ -11,21 +11,10 @@ import { safeLoad } from 'js-yaml'; import { set } from '@kbn/safer-lodash-set'; import { isPlainObject } from 'lodash'; import { ensureValidObjectPath } from '@kbn/std'; -import { splitKey, getUnsplittableKey } from './utils'; +import { splitKey, getUnsplittableKey, replaceEnvVarRefs } from './utils'; const readYaml = (path: string) => safeLoad(readFileSync(path, 'utf8')); -function replaceEnvVarRefs(val: string) { - return val.replace(/\$\{(\w+)\}/g, (match, envVarName) => { - const envVarValue = process.env[envVarName]; - if (envVarValue !== undefined) { - return envVarValue; - } - - throw new Error(`Unknown environment variable referenced in config : ${envVarName}`); - }); -} - interface YamlEntry { path: string[]; value: any; diff --git a/packages/kbn-config/src/raw/utils.test.ts b/packages/kbn-config/src/raw/utils.test.ts index 26ecba09d9a98..0dc96ef4593d0 100644 --- a/packages/kbn-config/src/raw/utils.test.ts +++ b/packages/kbn-config/src/raw/utils.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { splitKey, getUnsplittableKey } from './utils'; +import { splitKey, getUnsplittableKey, replaceEnvVarRefs } from './utils'; describe('splitKey', () => { it('correctly splits on the dot delimiter', () => { @@ -33,3 +33,39 @@ describe('getUnsplittableKey', () => { expect(getUnsplittableKey('foo.bar')).toEqual(undefined); }); }); + +describe('replaceEnvVarRefs', () => { + it('throws an error if the variable is not defined', () => { + expect(() => replaceEnvVarRefs('${VAR_1}', {})).toThrowErrorMatchingInlineSnapshot( + `"Unknown environment variable referenced in config : VAR_1"` + ); + }); + it('replaces the environment variable with its value', () => { + expect(replaceEnvVarRefs('${VAR_1}', { VAR_1: 'foo' })).toEqual('foo'); + }); + it('replaces the environment variable within a longer string', () => { + expect(replaceEnvVarRefs('hello ${VAR_1} bar', { VAR_1: 'foo' })).toEqual('hello foo bar'); + }); + it('replaces multiple occurrences of the same variable', () => { + expect(replaceEnvVarRefs('${VAR_1}-${VAR_1}', { VAR_1: 'foo' })).toEqual('foo-foo'); + }); + it('replaces multiple occurrences of different variables', () => { + expect(replaceEnvVarRefs('${VAR_1}-${VAR_2}', { VAR_1: 'foo', VAR_2: 'bar' })).toEqual( + 'foo-bar' + ); + }); + it('uses the default value if specified and the var is not defined', () => { + expect(replaceEnvVarRefs('${VAR:default}', {})).toEqual('default'); + }); + it('uses the value from the var if specified even with a default value', () => { + expect(replaceEnvVarRefs('${VAR:default}', { VAR: 'value' })).toEqual('value'); + }); + it('supports defining a default value for multiple variables', () => { + expect(replaceEnvVarRefs('${VAR1:var}:${VAR2:var2}', {})).toEqual('var:var2'); + }); + it('only use default value for variables that are not set', () => { + expect(replaceEnvVarRefs('${VAR1:default1}:${VAR2:default2}', { VAR2: 'var2' })).toEqual( + 'default1:var2' + ); + }); +}); diff --git a/packages/kbn-config/src/raw/utils.ts b/packages/kbn-config/src/raw/utils.ts index b44a3c14477aa..6fbcd767bafc3 100644 --- a/packages/kbn-config/src/raw/utils.ts +++ b/packages/kbn-config/src/raw/utils.ts @@ -19,3 +19,25 @@ export const getUnsplittableKey = (rawKey: string): string | undefined => { } return undefined; }; + +export function replaceEnvVarRefs( + val: string, + env: { + [key: string]: string | undefined; + } = process.env +) { + return val.replace(/\$\{(\w+)(:(\w+))?\}/g, (match, ...groups) => { + const envVarName = groups[0]; + const defaultValue = groups[2]; + + const envVarValue = env[envVarName]; + if (envVarValue !== undefined) { + return envVarValue; + } + if (defaultValue !== undefined) { + return defaultValue; + } + + throw new Error(`Unknown environment variable referenced in config : ${envVarName}`); + }); +} From e10dd38768da47cb883631108020443da5f1ce05 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 06:56:06 +0100 Subject: [PATCH 086/104] fix(NA): type failures --- .../dashboard_container/embeddable/create/create_dashboard.ts | 2 +- .../public/components/hooks/workpad/use_incoming_embeddable.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts index 483de4df70577..23d677b3e47c5 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts @@ -306,7 +306,7 @@ export const initializeDashboard = async ({ // -------------------------------------------------------------------------------------- // Place the incoming embeddable if there is one // -------------------------------------------------------------------------------------- - const incomingEmbeddable = creationOptions?.getIncomingEmbeddable?.(); + const incomingEmbeddable = creationOptions?.getIncomingEmbeddable?.() as any; if (incomingEmbeddable) { const scrolltoIncomingEmbeddable = (container: DashboardContainer, id: string) => { container.setScrollToPanelId(id); diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts index 0a4e66917814d..5bb3e5ed6050c 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts @@ -40,7 +40,7 @@ export const useIncomingEmbeddable = (selectedPage: CanvasPage) => { useEffect(() => { if (isByValueEnabled && incomingEmbeddable) { - const { embeddableId, input: incomingInput, type } = incomingEmbeddable; + const { embeddableId, input: incomingInput, type } = incomingEmbeddable as any; // retrieve existing element const originalElement = selectedPage.elements.find( From 465daa77cb155a144754b5bf74d0d87d63417847 Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Wed, 1 May 2024 02:01:05 -0400 Subject: [PATCH 087/104] Adding alerts to the data telemetry (#182184) ## Summary Previously, alerts were not included in the data telemetry. This caused complications when trying to assess the storage required for alerts. This PR adds alerts to the standard data telemetry. ### Checklist Delete any items that are not applicable to this PR. - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### Risk Matrix N/A ### For maintainers - [X] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../telemetry_collection/get_data_telemetry/constants.ts | 1 + .../get_data_telemetry/get_data_telemetry.test.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts index ed5bb95ec5ef1..f2f143a7c61b5 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts @@ -63,6 +63,7 @@ export const DATA_DATASETS_INDEX_PATTERNS = [ { pattern: 'winlogbeat-*', patternName: 'winlogbeat', shipper: 'winlogbeat' }, { pattern: 'packetbeat-*', patternName: 'packetbeat', shipper: 'packetbeat' }, { pattern: 'filebeat-*', patternName: 'filebeat', shipper: 'filebeat' }, + { pattern: '.internal.alerts-*', patternName: 'alerts' }, // Security - 3rd party { pattern: '*apache*', patternName: 'apache' }, // Already in Observability (keeping it in here for documentation) { pattern: '*tomcat*', patternName: 'tomcat' }, diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts index cc4bf29166488..20fbf231aa12a 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts @@ -71,6 +71,7 @@ describe('get_data_telemetry', () => { { name: 'filebeat-12314', docCount: 100, sizeInBytes: 10 }, { name: 'metricbeat-1234', docCount: 100, sizeInBytes: 10, isECS: false }, { name: '.app-search-1234', docCount: 0 }, + { name: '.internal.alerts-stack.alerts-default-0000001', sizeInBytes: 999 }, { name: 'logs-endpoint.1234', docCount: 0 }, // Matching pattern with a dot in the name { name: 'ml_host_risk_score_latest_default', docCount: 0 }, { name: 'ml_host_risk_score_latest', docCount: 0 }, // This should not match, @@ -165,6 +166,11 @@ describe('get_data_telemetry', () => { index_count: 1, doc_count: 0, }, + { + pattern_name: 'alerts', + index_count: 1, + size_in_bytes: 999, + }, { pattern_name: 'logs-endpoint', shipper: 'endpoint', From 4262afe43c4e9158beabc456e9c92f7f26f3b359 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 1 May 2024 08:26:25 +0200 Subject: [PATCH 088/104] [ES|QL] Fetch the query columns utils (#181969) ## Summary Adds a new utility for the users who want to retrieve the columns from a query without expressions but using the search strategy. This is the first utility to add for fetching ES|QL data without expressions. This is only for columns but we can extend for fetching the entire table instead. The latter will be part of https://github.com/elastic/kibana/issues/179641#issuecomment-2068556150 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-esql-utils/index.ts | 1 + packages/kbn-esql-utils/src/index.ts | 1 + .../src/utils/run_query_utils.ts | 52 +++++++++++++++++ packages/kbn-esql-utils/tsconfig.json | 4 ++ .../shared/edit_on_the_fly/helpers.test.ts | 57 +++++++++---------- .../shared/edit_on_the_fly/helpers.ts | 38 ++++--------- .../public/editor_frame_service/mocks.tsx | 2 +- .../open_lens_config/create_action_helpers.ts | 20 +++---- 8 files changed, 107 insertions(+), 68 deletions(-) create mode 100644 packages/kbn-esql-utils/src/utils/run_query_utils.ts diff --git a/packages/kbn-esql-utils/index.ts b/packages/kbn-esql-utils/index.ts index 0d04f40b85612..9272eddb4debd 100644 --- a/packages/kbn-esql-utils/index.ts +++ b/packages/kbn-esql-utils/index.ts @@ -17,6 +17,7 @@ export { getESQLWithSafeLimit, appendToESQLQuery, TextBasedLanguages, + getESQLQueryColumns, } from './src'; export { ESQL_LATEST_VERSION } from './constants'; diff --git a/packages/kbn-esql-utils/src/index.ts b/packages/kbn-esql-utils/src/index.ts index 92a39a4a6f793..a637ab0574d5e 100644 --- a/packages/kbn-esql-utils/src/index.ts +++ b/packages/kbn-esql-utils/src/index.ts @@ -17,3 +17,4 @@ export { removeDropCommandsFromESQLQuery, } from './utils/query_parsing_helpers'; export { appendToESQLQuery } from './utils/append_to_query'; +export { getESQLQueryColumns } from './utils/run_query_utils'; diff --git a/packages/kbn-esql-utils/src/utils/run_query_utils.ts b/packages/kbn-esql-utils/src/utils/run_query_utils.ts new file mode 100644 index 0000000000000..1512c86b2b8bf --- /dev/null +++ b/packages/kbn-esql-utils/src/utils/run_query_utils.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DatatableColumn } from '@kbn/expressions-plugin/common'; +import type { ISearchStart } from '@kbn/data-plugin/public'; +import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; +import type { ESQLSearchReponse } from '@kbn/es-types'; +import { lastValueFrom } from 'rxjs'; +import { ESQL_LATEST_VERSION } from '../../constants'; + +export async function getESQLQueryColumns({ + esqlQuery, + search, + signal, +}: { + esqlQuery: string; + search: ISearchStart; + signal?: AbortSignal; +}): Promise { + const response = await lastValueFrom( + search.search( + { + params: { + query: `${esqlQuery} | limit 0`, + version: ESQL_LATEST_VERSION, + }, + }, + { + abortSignal: signal, + strategy: 'esql_async', + } + ) + ); + + const columns = + (response.rawResponse as unknown as ESQLSearchReponse).columns?.map(({ name, type }) => { + const kibanaType = esFieldTypeToKibanaFieldType(type); + const column = { + id: name, + name, + meta: { type: kibanaType, esType: type }, + } as DatatableColumn; + + return column; + }) ?? []; + + return columns; +} diff --git a/packages/kbn-esql-utils/tsconfig.json b/packages/kbn-esql-utils/tsconfig.json index 5a494e9929d7b..1185d03b56448 100644 --- a/packages/kbn-esql-utils/tsconfig.json +++ b/packages/kbn-esql-utils/tsconfig.json @@ -17,8 +17,12 @@ ], "kbn_references": [ "@kbn/data-views-plugin", + "@kbn/data-plugin", "@kbn/crypto-browser", "@kbn/data-view-utils", "@kbn/esql-ast", + "@kbn/expressions-plugin", + "@kbn/field-types", + "@kbn/es-types", ] } diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts index 57638b61db1a9..fcdb83a978f6a 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts @@ -5,7 +5,7 @@ * 2.0. */ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { fetchFieldsFromESQL } from '@kbn/text-based-editor'; +import { getESQLQueryColumns } from '@kbn/esql-utils'; import type { LensPluginStartDependencies } from '../../../plugin'; import { createMockStartDependencies } from '../../../editor_frame_service/mocks'; import { @@ -18,45 +18,44 @@ import { suggestionsApi } from '../../../lens_suggestions_api'; import { getSuggestions } from './helpers'; const mockSuggestionApi = suggestionsApi as jest.Mock; -const mockFetchData = fetchFieldsFromESQL as jest.Mock; +const mockFetchData = getESQLQueryColumns as jest.Mock; jest.mock('../../../lens_suggestions_api', () => ({ suggestionsApi: jest.fn(() => mockAllSuggestions), })); -jest.mock('@kbn/text-based-editor', () => ({ - fetchFieldsFromESQL: jest.fn(() => { - return { - columns: [ - { - name: '@timestamp', - id: '@timestamp', - meta: { - type: 'date', - }, +jest.mock('@kbn/esql-utils', () => { + return { + getESQLQueryColumns: jest.fn().mockResolvedValue(() => [ + { + name: '@timestamp', + id: '@timestamp', + meta: { + type: 'date', }, - { - name: 'bytes', - id: 'bytes', - meta: { - type: 'number', - }, + }, + { + name: 'bytes', + id: 'bytes', + meta: { + type: 'number', }, - { - name: 'memory', - id: 'memory', - meta: { - type: 'number', - }, + }, + { + name: 'memory', + id: 'memory', + meta: { + type: 'number', }, - ], - }; - }), -})); + }, + ]), + getIndexPatternFromESQLQuery: jest.fn().mockReturnValue('index1'), + }; +}); describe('getSuggestions', () => { const query = { - esql: 'from index1 | limit 10 | stats average = avg(bytes', + esql: 'from index1 | limit 10 | stats average = avg(bytes)', }; const mockStartDependencies = createMockStartDependencies() as unknown as LensPluginStartDependencies; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts index 803fcbf169935..9ab8b5fc05aef 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts @@ -4,39 +4,20 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { getIndexPatternFromSQLQuery, getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; +import { + getIndexPatternFromSQLQuery, + getIndexPatternFromESQLQuery, + getESQLAdHocDataview, + getESQLQueryColumns, +} from '@kbn/esql-utils'; import type { AggregateQuery } from '@kbn/es-query'; -import { getESQLAdHocDataview } from '@kbn/esql-utils'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; -import { fetchFieldsFromESQL } from '@kbn/text-based-editor'; import type { DataViewSpec } from '@kbn/data-views-plugin/public'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; import type { LensPluginStartDependencies } from '../../../plugin'; import type { DatasourceMap, VisualizationMap } from '../../../types'; import { suggestionsApi } from '../../../lens_suggestions_api'; -export const getQueryColumns = async ( - query: AggregateQuery, - deps: LensPluginStartDependencies, - abortController?: AbortController -) => { - // Fetching only columns for ES|QL for performance reasons with limit 0 - // Important note: ES doesnt return the warnings for 0 limit, - // I am skipping them in favor of performance now - // but we should think another way to get them (from Lens embeddable or store) - const performantQuery = { ...query }; - if ('esql' in performantQuery && performantQuery.esql) { - performantQuery.esql = `${performantQuery.esql} | limit 0`; - } - const table = await fetchFieldsFromESQL( - performantQuery, - deps.expressions, - undefined, - abortController - ); - return table?.columns; -}; - export const getSuggestions = async ( query: AggregateQuery, deps: LensPluginStartDependencies, @@ -65,7 +46,12 @@ export const getSuggestions = async ( if (dataView.fields.getByName('@timestamp')?.type === 'date' && !dataViewSpec) { dataView.timeFieldName = '@timestamp'; } - const columns = await getQueryColumns(query, deps, abortController); + + const columns = await getESQLQueryColumns({ + esqlQuery: 'esql' in query ? query.esql : '', + search: deps.data.search, + signal: abortController?.signal, + }); const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', diff --git a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx index 4513e0f4bffd4..eacbbc079413d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx @@ -55,7 +55,7 @@ export function createMockSetupDependencies() { export function createMockStartDependencies() { return { - data: dataPluginMock.createSetupContract(), + data: dataPluginMock.createStartContract(), embeddable: embeddablePluginMock.createStartContract(), expressions: expressionsPluginMock.createStartContract(), charts: chartPluginMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts index 3e77f8979a872..0d6f85e7703ad 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts @@ -6,13 +6,13 @@ */ import { createGetterSetter } from '@kbn/kibana-utils-plugin/common'; import type { CoreStart } from '@kbn/core/public'; +import { getESQLQueryColumns } from '@kbn/esql-utils'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { PresentationContainer } from '@kbn/presentation-containers'; import { getESQLAdHocDataview, getIndexForESQLQuery } from '@kbn/esql-utils'; import type { Datasource, Visualization } from '../../types'; import type { LensPluginStartDependencies } from '../../plugin'; -import { fetchDataFromAggregateQuery } from '../../datasources/text_based/fetch_data_from_aggregate_query'; import { suggestionsApi } from '../../lens_suggestions_api'; import { generateId } from '../../id_generator'; import { executeEditAction } from './edit_action_helpers'; @@ -66,21 +66,17 @@ export async function executeCreateAction({ // so we are requesting them with limit 0 // this is much more performant than requesting // all the table - const performantQuery = { - esql: `from ${defaultIndex} | limit 0`, - }; - - const table = await fetchDataFromAggregateQuery( - performantQuery, - dataView, - deps.data, - deps.expressions - ); + const abortController = new AbortController(); + const columns = await getESQLQueryColumns({ + esqlQuery: `from ${defaultIndex}`, + search: deps.data.search, + signal: abortController.signal, + }); const context = { dataViewSpec: dataView.toSpec(), fieldName: '', - textBasedColumns: table?.columns, + textBasedColumns: columns, query: defaultEsqlQuery, }; From 900c26c3b5f67069d8b6ffa58e1c461faac64901 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 1 May 2024 08:30:10 +0200 Subject: [PATCH 089/104] [ES|QL] Moves ES|QL data visualizer to GA (#182075) ## Summary Removes technical preview badges from ES|QL data visualizer --- .../datavisualizer_selector.tsx | 21 ------------------- .../index_based/index_data_visualizer.tsx | 8 +------ .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 5 files changed, 1 insertion(+), 31 deletions(-) diff --git a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx index 051219481118d..1b5f3acdaedd2 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx @@ -18,11 +18,9 @@ import { EuiLink, EuiSpacer, EuiText, - EuiBetaBadge, EuiTextAlign, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useTimefilter } from '@kbn/ml-date-picker'; import { ENABLE_ESQL } from '@kbn/discover-utils'; @@ -174,25 +172,6 @@ export const DatavisualizerSelector: FC = () => { {' '} - - } - tooltipPosition={'right'} - aria-label={i18n.translate( - 'xpack.ml.datavisualizer.selector.technicalPreviewBadge.ariaLabel', - { - defaultMessage: 'ES|QL is in technical preview.', - } - )} /> diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx index 3b3e673f3c59c..157aa89522d75 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx @@ -16,7 +16,7 @@ import type { GetAdditionalLinksParams, } from '@kbn/data-visualizer-plugin/public'; import { useTimefilter } from '@kbn/ml-date-picker'; -import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import useMountedState from 'react-use/lib/useMountedState'; import { useMlKibana, useMlLocator } from '../../contexts/kibana'; import { HelpMenu } from '../../components/help_menu'; @@ -26,7 +26,6 @@ import { mlNodesAvailable, getMlNodeCount } from '../../ml_nodes_check/check_ml_ import { checkPermission } from '../../capabilities/check_capabilities'; import { MlPageHeader } from '../../components/page_header'; import { useEnabledFeatures } from '../../contexts/ml'; -import { TechnicalPreviewBadge } from '../../components/technical_preview_badge/technical_preview_badge'; export const IndexDataVisualizerPage: FC<{ esql: boolean }> = ({ esql = false }) => { useTimefilter({ timeRangeSelector: false, autoRefreshSelector: false }); const { @@ -188,8 +187,6 @@ export const IndexDataVisualizerPage: FC<{ esql: boolean }> = ({ esql = false }) // eslint-disable-next-line react-hooks/exhaustive-deps [mlLocator, mlFeaturesDisabled] ); - const { euiTheme } = useEuiTheme(); - return IndexDataVisualizer ? ( {IndexDataVisualizer !== null ? ( @@ -205,9 +202,6 @@ export const IndexDataVisualizerPage: FC<{ esql: boolean }> = ({ esql = false }) - - - ) : null} diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 60c21cfc74cdd..d65c505c95ea7 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -26460,7 +26460,6 @@ "xpack.ml.datavisualizer.selector.startTrialButtonLabel": "Commencer l'essai", "xpack.ml.datavisualizer.selector.startTrialTitle": "Commencer l'essai", "xpack.ml.datavisualizer.selector.technicalPreviewBadge.contentMsg": "Utilisez les requêtes ES|QL pour visualiser les informations de n'importe quel ensemble de données.", - "xpack.ml.datavisualizer.selector.technicalPreviewBadge.titleMsg": "ES|QL est en version d'évaluation technique.", "xpack.ml.datavisualizer.selector.uploadFileButtonLabel": "Sélectionner un fichier", "xpack.ml.datavisualizer.selector.useESQLButtonLabel": "Utiliser ES|QL", "xpack.ml.datavisualizer.startTrial.subscriptionsLinkText": "Abonnement Platinum ou Enterprise", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 6ea7973b93a11..a90eb95137a9c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -26433,7 +26433,6 @@ "xpack.ml.datavisualizer.selector.startTrialButtonLabel": "トライアルを開始", "xpack.ml.datavisualizer.selector.startTrialTitle": "トライアルを開始", "xpack.ml.datavisualizer.selector.technicalPreviewBadge.contentMsg": "ES|QLクエリを使用して、データセットに関する情報を可視化します。", - "xpack.ml.datavisualizer.selector.technicalPreviewBadge.titleMsg": "ES|QLはテクニカルプレビューです。", "xpack.ml.datavisualizer.selector.uploadFileButtonLabel": "ファイルを選択", "xpack.ml.datavisualizer.selector.useESQLButtonLabel": "ES|QLを使用", "xpack.ml.datavisualizer.startTrial.subscriptionsLinkText": "PlatinumまたはEnterprise サブスクリプション", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4742b2168dc60..45b79ec3364c3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -26471,7 +26471,6 @@ "xpack.ml.datavisualizer.selector.startTrialButtonLabel": "开始试用", "xpack.ml.datavisualizer.selector.startTrialTitle": "开始试用", "xpack.ml.datavisualizer.selector.technicalPreviewBadge.contentMsg": "使用 ES|QL 查询可视化有关任何数据集的信息。", - "xpack.ml.datavisualizer.selector.technicalPreviewBadge.titleMsg": "ES|QL 处于技术预览状态。", "xpack.ml.datavisualizer.selector.uploadFileButtonLabel": "选择文件", "xpack.ml.datavisualizer.selector.useESQLButtonLabel": "使用 ES|QL", "xpack.ml.datavisualizer.startTrial.subscriptionsLinkText": "白金级或企业级订阅", From 1633c0b3a70194a45d126bcbc946a0810db5a897 Mon Sep 17 00:00:00 2001 From: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com> Date: Wed, 1 May 2024 09:16:34 +0100 Subject: [PATCH 090/104] [Security Solution][Detection Engine] use ES|QL metadata operator without square brackets (#182114) ## Summary ES|QL metadata operator has changed its syntax: https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-metadata-fields.html from ``` FROM index [METADATA _index, _id] ``` to ``` FROM index METADATA _index, _id ``` This PR removes square brackets as required symbols for metadata operator. Deprecated one still supported by ES|QL, but shows warning --- .../logic/esql_validator.test.ts | 13 +++++ .../rule_creation/logic/esql_validator.ts | 6 +-- .../rule_creation/logic/translations.ts | 2 +- .../hooks/use_esql_index.test.ts | 2 +- .../hooks/use_investigation_fields.test.ts | 2 +- .../execution_logic/esql.ts | 52 ++++++++++++++++--- .../rule_creation/esql_rule_ess.cy.ts | 12 ++--- 7 files changed, 70 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.test.ts index 162fe94ecad70..889d74a1c6503 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.test.ts @@ -17,6 +17,19 @@ describe('computeHasMetadataOperator', () => { expect(computeHasMetadataOperator('from test* | eval x="[metadata _id]"')).toBe(false); }); it('should be true if query has operator', () => { + expect(computeHasMetadataOperator('from test* metadata _id')).toBe(true); + expect(computeHasMetadataOperator('from test* metadata _id, _index')).toBe(true); + expect(computeHasMetadataOperator('from test* metadata _index, _id')).toBe(true); + expect(computeHasMetadataOperator('from test* metadata _id ')).toBe(true); + expect(computeHasMetadataOperator('from test* metadata _id | limit 10')).toBe(true); + expect( + computeHasMetadataOperator(`from packetbeat* metadata + + _id + | limit 100`) + ).toBe(true); + + // still validates deprecated square bracket syntax expect(computeHasMetadataOperator('from test* [metadata _id]')).toBe(true); expect(computeHasMetadataOperator('from test* [metadata _id, _index]')).toBe(true); expect(computeHasMetadataOperator('from test* [metadata _index, _id]')).toBe(true); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.ts index 9cadae108ac22..e7a6e523965b2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/logic/esql_validator.ts @@ -36,10 +36,10 @@ const constructValidationError = (error: Error) => { }; /** - * checks whether query has [metadata _id] operator + * checks whether query has metadata _id operator */ export const computeHasMetadataOperator = (esqlQuery: string) => { - return /(? export const ESQL_VALIDATION_MISSING_ID_IN_QUERY_ERROR = i18n.translate( 'xpack.securitySolution.detectionEngine.esqlValidation.missingIdInQueryError', { - defaultMessage: `Queries that don’t use the STATS...BY function (non-aggregating queries) must include the [metadata _id, _version, _index] operator after the source command. For example: FROM logs* [metadata _id, _version, _index]. In addition, the metadata properties (_id, _version, and _index) must be returned in the query response.`, + defaultMessage: `Queries that don’t use the STATS...BY function (non-aggregating queries) must include the "metadata _id, _version, _index" operator after the source command. For example: FROM logs* metadata _id, _version, _index. In addition, the metadata properties (_id, _version, and _index) must be returned in the query response.`, } ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts index cde92602611ac..dc4394be257e5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts @@ -8,7 +8,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { useEsqlIndex } from './use_esql_index'; -const validEsqlQuery = 'from auditbeat* [metadata _id, _index, _version]'; +const validEsqlQuery = 'from auditbeat* metadata _id, _index, _version'; describe('useEsqlIndex', () => { it('should return empty array if isQueryReadEnabled is undefined', () => { const { result } = renderHook(() => useEsqlIndex(validEsqlQuery, 'esql', undefined)); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_investigation_fields.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_investigation_fields.test.ts index 4819f87d5a41f..6a159f87d89d8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_investigation_fields.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_investigation_fields.test.ts @@ -28,7 +28,7 @@ const fetchFieldsFromESQLMock = fetchFieldsFromESQL as jest.Mock; const { wrapper } = createQueryWrapperMock(); -const mockEsqlQuery = 'from auditbeat* [metadata _id]'; +const mockEsqlQuery = 'from auditbeat* metadata _id'; const mockIndexPatternFields: DataViewFieldBase[] = [ { name: 'agent.name', diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/esql.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/esql.ts index 7fd34aff67690..c629f5056ef3a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/esql.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/esql.ts @@ -66,7 +66,7 @@ export default ({ getService }: FtrProviderContext) => { const interval: [string, string] = ['2020-10-28T06:00:00.000Z', '2020-10-28T06:10:00.000Z']; const doc1 = { agent: { name: 'test-1' } }; const doc2 = { agent: { name: 'test-2' } }; - const ruleQuery = `from ecs_compliant [metadata _id, _index, _version] ${internalIdPipe( + const ruleQuery = `from ecs_compliant metadata _id, _index, _version ${internalIdPipe( id )} | where agent.name=="test-1"`; const rule: EsqlRuleCreateProps = { @@ -243,7 +243,7 @@ export default ({ getService }: FtrProviderContext) => { const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock('rule-1', true), // only _id and agent.name is projected at the end of query pipeline - query: `from ecs_compliant [metadata _id] ${internalIdPipe(id)} | keep _id, agent.name`, + query: `from ecs_compliant metadata _id ${internalIdPipe(id)} | keep _id, agent.name`, from: 'now-1h', interval: '1h', }; @@ -278,6 +278,44 @@ export default ({ getService }: FtrProviderContext) => { ); }); + it('should support deprecated [metadata _id] syntax', async () => { + const id = uuidv4(); + const interval: [string, string] = ['2020-10-28T06:00:00.000Z', '2020-10-28T06:10:00.000Z']; + const doc1 = { + agent: { name: 'test-1', version: '2', type: 'auditbeat' }, + host: { name: 'my-host' }, + client: { ip: '127.0.0.1' }, + }; + + const rule: EsqlRuleCreateProps = { + ...getCreateEsqlRulesSchemaMock('rule-1', true), + // only _id and agent.name is projected at the end of query pipeline + query: `from ecs_compliant [metadata _id] ${internalIdPipe(id)} | keep _id, agent.name`, + from: 'now-1h', + interval: '1h', + }; + + await indexEnhancedDocuments({ + documents: [doc1], + interval, + id, + }); + + const { previewId } = await previewRule({ + supertest, + rule, + timeframeEnd: new Date('2020-10-28T06:30:00.000Z'), + }); + + const previewAlerts = await getPreviewAlerts({ + es, + previewId, + size: 10, + }); + + expect(previewAlerts.length).toBe(1); + }); + it('should deduplicate alerts correctly based on source document _id', async () => { const id = uuidv4(); // document will fall into 2 rule execution windows @@ -290,7 +328,7 @@ export default ({ getService }: FtrProviderContext) => { const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock('rule-1', true), // only _id and agent.name is projected at the end of query pipeline - query: `from ecs_compliant [metadata _id] ${internalIdPipe(id)} | keep _id, agent.name`, + query: `from ecs_compliant metadata _id ${internalIdPipe(id)} | keep _id, agent.name`, from: 'now-45m', interval: '30m', }; @@ -725,7 +763,7 @@ export default ({ getService }: FtrProviderContext) => { const id = uuidv4(); const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock(`rule-${id}`, true), - query: `from ecs_compliant [metadata _id] ${internalIdPipe( + query: `from ecs_compliant metadata _id ${internalIdPipe( id )} | keep _id, agent.name | sort agent.name`, from: '2020-10-28T05:15:00.000Z', @@ -913,7 +951,7 @@ export default ({ getService }: FtrProviderContext) => { const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock('rule-1', true), - query: `from ecs_compliant [metadata _id] ${internalIdPipe( + query: `from ecs_compliant metadata _id ${internalIdPipe( id )} | where agent.name=="test-1"`, from: 'now-1h', @@ -956,7 +994,7 @@ export default ({ getService }: FtrProviderContext) => { const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock('rule-1', true), - query: `from ecs_compliant [metadata _id] ${internalIdPipe( + query: `from ecs_compliant metadata _id ${internalIdPipe( id )} | where agent.name=="test-1"`, from: 'now-1h', @@ -1021,7 +1059,7 @@ export default ({ getService }: FtrProviderContext) => { const rule: EsqlRuleCreateProps = { ...getCreateEsqlRulesSchemaMock('rule-1', true), - query: `from ecs_non_compliant [metadata _id] ${internalIdPipe(id)}`, + query: `from ecs_non_compliant metadata _id ${internalIdPipe(id)}`, from: 'now-1h', interval: '1h', }; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/esql_rule_ess.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/esql_rule_ess.cy.ts index 945cf43967cbe..2e95bb19a0477 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/esql_rule_ess.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/esql_rule_ess.cy.ts @@ -138,7 +138,7 @@ describe('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { cy.get(ESQL_QUERY_BAR).should('not.be.visible'); }); - it('shows error when non-aggregating ES|QL query does not [metadata] operator', function () { + it('shows error when non-aggregating ES|QL query does not have metadata operator', function () { workaroundForResizeObserver(); const invalidNonAggregatingQuery = 'from auditbeat* | limit 5'; @@ -148,7 +148,7 @@ describe('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { getDefineContinueButton().click(); cy.get(ESQL_QUERY_BAR).contains( - 'must include the [metadata _id, _version, _index] operator after the source command' + 'must include the "metadata _id, _version, _index" operator after the source command' ); }); @@ -156,7 +156,7 @@ describe('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { workaroundForResizeObserver(); const invalidNonAggregatingQuery = - 'from auditbeat* [metadata _id, _version, _index] | keep agent.* | limit 5'; + 'from auditbeat* metadata _id, _version, _index | keep agent.* | limit 5'; selectEsqlRuleType(); expandEsqlQueryBar(); @@ -164,14 +164,14 @@ describe('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { getDefineContinueButton().click(); cy.get(ESQL_QUERY_BAR).contains( - 'must include the [metadata _id, _version, _index] operator after the source command' + 'must include the "metadata _id, _version, _index" operator after the source command' ); }); it('shows error when ES|QL query is invalid', function () { workaroundForResizeObserver(); const invalidEsqlQuery = - 'from auditbeat* [metadata _id, _version, _index] | not_existing_operator'; + 'from auditbeat* metadata _id, _version, _index | not_existing_operator'; visit(CREATE_RULE_URL); selectEsqlRuleType(); @@ -191,7 +191,7 @@ describe('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { it('shows custom ES|QL field in investigation fields autocomplete and saves it in rule', function () { const CUSTOM_ESQL_FIELD = '_custom_agent_name'; const queryWithCustomFields = [ - `from auditbeat* [metadata _id, _version, _index]`, + `from auditbeat* metadata _id, _version, _index`, `eval ${CUSTOM_ESQL_FIELD} = agent.name`, `keep _id, _custom_agent_name`, `limit 5`, From 7fc54940fbdae4bb7ff72928f7945a66024a3282 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 1 May 2024 10:45:21 +0200 Subject: [PATCH 091/104] [HTTP] Remove `description` from `options` in versioned router options (#181989) ## Summary Ensure that we only provide one option for providing `description` to versioned routes. --- packages/core/http/core-http-server/src/versioning/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/http/core-http-server/src/versioning/types.ts b/packages/core/http/core-http-server/src/versioning/types.ts index baa550b253544..b7aed68438fdb 100644 --- a/packages/core/http/core-http-server/src/versioning/types.ts +++ b/packages/core/http/core-http-server/src/versioning/types.ts @@ -32,7 +32,7 @@ export type VersionedRouteConfig = Omit< RouteConfig, 'validate' | 'options' > & { - options?: Omit, 'access'>; + options?: Omit, 'access' | 'description'>; /** See {@link RouteConfigOptions['access']} */ access: Exclude['access'], undefined>; /** From 151aab5c15fbc673aebe78672898d4adce6cdc59 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 1 May 2024 13:03:41 +0200 Subject: [PATCH 092/104] [SLOs] Add details page history tab (#181150) ## Summary This will allow users to view data beyond default values in details page chart, users will be able to select date range via picker to view historical SLI, Burn rate or Good/Bad Events chart https://github.com/elastic/kibana/assets/3505601/48a6a029-ad36-4457-b195-4ab2d739fca0 image --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../routes/fetch_historical_summary.ts | 8 +- .../kbn-slo-schema/src/schema/common.ts | 5 +- .../slo/common/locators/paths.ts | 10 +- .../slo/burn_rate/burn_rate_header.tsx | 55 ++++++++ .../components/slo/burn_rate/burn_rates.tsx | 70 +++++----- .../slo/error_rate_chart/error_rate_chart.tsx | 21 ++- .../error_rate_chart/use_lens_definition.ts | 55 +++++--- .../slo/common/slo_overview_details.tsx | 4 +- .../hooks/use_fetch_historical_summary.ts | 6 + .../components/error_budget_chart.tsx | 44 +++--- .../components/error_budget_chart_panel.tsx | 15 +- .../components/error_budget_header.tsx | 25 ++-- .../components/events_chart_panel.tsx | 27 ++-- .../components/historical_data_charts.tsx | 75 ++++++++++ .../history/slo_details_history.tsx | 128 ++++++++++++++++++ .../components/sli_chart_panel.tsx | 77 ++++++----- .../slo_details/components/slo_details.tsx | 118 ++++------------ .../slo_details/components/wide_chart.tsx | 19 ++- .../hooks/use_burn_rate_options.ts | 72 ++++++++++ .../slo_details/hooks/use_selected_tab.ts | 38 ++++++ .../hooks/use_slo_details_tabs.tsx | 69 +++++++++- .../pages/slo_details/slo_details.test.tsx | 1 + .../public/pages/slo_details/slo_details.tsx | 21 +-- .../slo/public/pages/slo_details/types.ts | 8 ++ .../common/good_bad_events_chart.tsx | 18 ++- .../slo/public/utils/slo/duration.ts | 8 ++ .../slo/server/services/burn_rates_client.ts | 3 +- .../services/historical_summary_client.ts | 18 ++- .../server/services/summary_client.test.ts | 8 +- .../slo/server/services/summary_client.ts | 3 +- .../observability_solution/slo/tsconfig.json | 1 + 31 files changed, 761 insertions(+), 269 deletions(-) create mode 100644 x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rate_header.tsx create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/historical_data_charts.tsx create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/history/slo_details_history.tsx create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_burn_rate_options.ts create mode 100644 x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_selected_tab.ts diff --git a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/fetch_historical_summary.ts b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/fetch_historical_summary.ts index c60fe499fdec5..0df546beecc4c 100644 --- a/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/fetch_historical_summary.ts +++ b/x-pack/packages/kbn-slo-schema/src/rest_specs/routes/fetch_historical_summary.ts @@ -31,7 +31,13 @@ const fetchHistoricalSummaryParamsSchema = t.type({ groupBy: allOrAnyStringOrArray, revision: t.number, }), - t.partial({ remoteName: t.string }), + t.partial({ + remoteName: t.string, + range: t.type({ + from: t.string, + to: t.string, + }), + }), ]) ), }), diff --git a/x-pack/packages/kbn-slo-schema/src/schema/common.ts b/x-pack/packages/kbn-slo-schema/src/schema/common.ts index 155164dee593f..5346b9507e0b9 100644 --- a/x-pack/packages/kbn-slo-schema/src/schema/common.ts +++ b/x-pack/packages/kbn-slo-schema/src/schema/common.ts @@ -81,7 +81,10 @@ const groupSummarySchema = t.type({ noData: t.number, }); -const dateRangeSchema = t.type({ from: dateType, to: dateType }); +const dateRangeSchema = t.type({ + from: t.union([dateType, t.string]), + to: t.union([dateType, t.string]), +}); export { ALL_VALUE, diff --git a/x-pack/plugins/observability_solution/slo/common/locators/paths.ts b/x-pack/plugins/observability_solution/slo/common/locators/paths.ts index 2f2a1b329543b..198b433e285a2 100644 --- a/x-pack/plugins/observability_solution/slo/common/locators/paths.ts +++ b/x-pack/plugins/observability_solution/slo/common/locators/paths.ts @@ -4,11 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + export const SLOS_BASE_PATH = '/app/slos'; export const SLO_PREFIX = '/slos'; export const SLOS_PATH = '/' as const; export const SLOS_WELCOME_PATH = '/welcome' as const; -export const SLO_DETAIL_PATH = '/:sloId' as const; +export const SLO_DETAIL_PATH = '/:sloId/:tabId?' as const; export const SLO_CREATE_PATH = '/create' as const; export const SLO_EDIT_PATH = '/edit/:sloId' as const; export const SLOS_OUTDATED_DEFINITIONS_PATH = '/outdated-definitions' as const; @@ -25,10 +26,13 @@ export const paths = { sloEdit: (sloId: string) => `${SLOS_BASE_PATH}/edit/${encodeURIComponent(sloId)}`, sloEditWithEncodedForm: (sloId: string, encodedParams: string) => `${SLOS_BASE_PATH}/edit/${encodeURIComponent(sloId)}?_a=${encodedParams}`, - sloDetails: (sloId: string, instanceId?: string, remoteName?: string) => { + sloDetails: (sloId: string, instanceId?: string, remoteName?: string, tabId?: string) => { const qs = new URLSearchParams(); - if (!!instanceId) qs.append('instanceId', instanceId); + if (!!instanceId && instanceId !== '*') qs.append('instanceId', instanceId); if (!!remoteName) qs.append('remoteName', remoteName); + if (tabId) { + return `${SLOS_BASE_PATH}/${encodeURIComponent(sloId)}/${tabId}?${qs.toString()}`; + } return `${SLOS_BASE_PATH}/${encodeURIComponent(sloId)}?${qs.toString()}`; }, }; diff --git a/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rate_header.tsx b/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rate_header.tsx new file mode 100644 index 0000000000000..5df9bcb2255b4 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rate_header.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { SloTabId } from '../../../pages/slo_details/components/slo_details'; +import { BurnRateOption } from './burn_rates'; +interface Props { + burnRateOption: BurnRateOption; + setBurnRateOption: (option: BurnRateOption) => void; + burnRateOptions: BurnRateOption[]; + selectedTabId: SloTabId; +} +export function BurnRateHeader({ + burnRateOption, + burnRateOptions, + setBurnRateOption, + selectedTabId, +}: Props) { + const onBurnRateOptionChange = (optionId: string) => { + const selected = burnRateOptions.find((opt) => opt.id === optionId) ?? burnRateOptions[0]; + setBurnRateOption(selected); + }; + return ( + + + +

    + {i18n.translate('xpack.slo.burnRate.title', { + defaultMessage: 'Burn rate', + })} +

    +
    +
    + {selectedTabId !== 'history' && ( + + ({ id: opt.id, label: opt.label }))} + idSelected={burnRateOption.id} + onChange={onBurnRateOptionChange} + buttonSize="compressed" + /> + + )} +
    + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rates.tsx b/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rates.tsx index b6c828f9a4df6..cb7555dfeaec3 100644 --- a/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rates.tsx +++ b/x-pack/plugins/observability_solution/slo/public/components/slo/burn_rate/burn_rates.tsx @@ -5,11 +5,14 @@ * 2.0. */ -import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import moment from 'moment'; import React, { useEffect, useState } from 'react'; +import { TimeBounds } from '../../../pages/slo_details/types'; +import { TimeRange } from '../error_rate_chart/use_lens_definition'; +import { SloTabId } from '../../../pages/slo_details/components/slo_details'; +import { BurnRateHeader } from './burn_rate_header'; import { useFetchSloBurnRates } from '../../../hooks/use_fetch_slo_burn_rates'; import { ErrorRateChart } from '../error_rate_chart'; import { BurnRate } from './burn_rate'; @@ -18,6 +21,9 @@ interface Props { slo: SLOWithSummaryResponse; isAutoRefreshing?: boolean; burnRateOptions: BurnRateOption[]; + selectedTabId: SloTabId; + range?: TimeRange; + onBrushed?: (timeBounds: TimeBounds) => void; } export interface BurnRateOption { @@ -32,7 +38,14 @@ function getWindowsFromOptions(opts: BurnRateOption[]): Array<{ name: string; du return opts.map((opt) => ({ name: opt.windowName, duration: `${opt.duration}h` })); } -export function BurnRates({ slo, isAutoRefreshing, burnRateOptions }: Props) { +export function BurnRates({ + slo, + isAutoRefreshing, + burnRateOptions, + selectedTabId, + range, + onBrushed, +}: Props) { const [burnRateOption, setBurnRateOption] = useState(burnRateOptions[0]); const { isLoading, data } = useFetchSloBurnRates({ slo, @@ -46,12 +59,7 @@ export function BurnRates({ slo, isAutoRefreshing, burnRateOptions }: Props) { } }, [burnRateOptions]); - const onBurnRateOptionChange = (optionId: string) => { - const selected = burnRateOptions.find((opt) => opt.id === optionId) ?? burnRateOptions[0]; - setBurnRateOption(selected); - }; - - const dataTimeRange = { + const dataTimeRange = range ?? { from: moment().subtract(burnRateOption.duration, 'hour').toDate(), to: new Date(), }; @@ -64,34 +72,26 @@ export function BurnRates({ slo, isAutoRefreshing, burnRateOptions }: Props) { return ( - - - -

    - {i18n.translate('xpack.slo.burnRate.title', { - defaultMessage: 'Burn rate', - })} -

    -
    -
    - - ({ id: opt.id, label: opt.label }))} - idSelected={burnRateOption.id} - onChange={onBurnRateOptionChange} - buttonSize="compressed" - /> - -
    + - - - + {selectedTabId !== 'history' && ( + + + + )} - +
    diff --git a/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/error_rate_chart.tsx b/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/error_rate_chart.tsx index 9353d1d574718..e42f5a9115bb6 100644 --- a/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/error_rate_chart.tsx +++ b/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/error_rate_chart.tsx @@ -9,6 +9,8 @@ import { ViewMode } from '@kbn/embeddable-plugin/public'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import moment from 'moment'; import React from 'react'; +import { SloTabId } from '../../../pages/slo_details/components/slo_details'; +import { TimeBounds } from '../../../pages/slo_details/types'; import { useKibana } from '../../../utils/kibana_react'; import { getDelayInSecondsFromSLO } from '../../../utils/slo/get_delay_in_seconds_from_slo'; import { AlertAnnotation, TimeRange, useLensDefinition } from './use_lens_definition'; @@ -20,6 +22,8 @@ interface Props { alertTimeRange?: TimeRange; showErrorRateAsLine?: boolean; annotations?: AlertAnnotation[]; + selectedTabId?: SloTabId; + onBrushed?: (timeBounds: TimeBounds) => void; } export function ErrorRateChart({ @@ -29,17 +33,20 @@ export function ErrorRateChart({ alertTimeRange, showErrorRateAsLine, annotations, + onBrushed, + selectedTabId, }: Props) { const { lens: { EmbeddableComponent }, } = useKibana().services; - const lensDef = useLensDefinition( + const lensDef = useLensDefinition({ slo, threshold, alertTimeRange, annotations, - showErrorRateAsLine - ); + showErrorRateAsLine, + selectedTabId, + }); const delayInSeconds = getDelayInSecondsFromSLO(slo); const from = moment(dataTimeRange.from).subtract(delayInSeconds, 'seconds').toISOString(); @@ -55,6 +62,14 @@ export function ErrorRateChart({ }} attributes={lensDef} viewMode={ViewMode.VIEW} + onBrushEnd={({ range }) => { + onBrushed?.({ + from: range[0], + to: range[1], + fromUtc: moment(range[0]).format(), + toUtc: moment(range[1]).format(), + }); + }} noPadding /> ); diff --git a/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/use_lens_definition.ts b/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/use_lens_definition.ts index a132076f8c2ed..513b26c6c2d18 100644 --- a/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/use_lens_definition.ts +++ b/x-pack/plugins/observability_solution/slo/public/components/slo/error_rate_chart/use_lens_definition.ts @@ -12,6 +12,7 @@ import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; import moment from 'moment'; import { v4 as uuidv4 } from 'uuid'; +import { SloTabId } from '../../../pages/slo_details/components/slo_details'; import { SLO_DESTINATION_INDEX_PATTERN } from '../../../../common/constants'; export interface TimeRange { @@ -24,13 +25,21 @@ export interface AlertAnnotation { total: number; } -export function useLensDefinition( - slo: SLOWithSummaryResponse, - threshold: number, - alertTimeRange?: TimeRange, - annotations?: AlertAnnotation[], - showErrorRateAsLine?: boolean -): TypedLensByValueInput['attributes'] { +export function useLensDefinition({ + slo, + threshold, + alertTimeRange, + annotations, + showErrorRateAsLine, + selectedTabId, +}: { + slo: SLOWithSummaryResponse; + threshold: number; + alertTimeRange?: TimeRange; + annotations?: AlertAnnotation[]; + showErrorRateAsLine?: boolean; + selectedTabId?: SloTabId; +}): TypedLensByValueInput['attributes'] { const { euiTheme } = useEuiTheme(); const interval = 'auto'; @@ -87,20 +96,24 @@ export function useLensDefinition( }, ], }, - { - layerId: '34298f84-681e-4fa3-8107-d6facb32ed92', - layerType: 'referenceLine', - accessors: ['0a42b72b-cd5a-4d59-81ec-847d97c268e6'], - yConfig: [ - { - forAccessor: '0a42b72b-cd5a-4d59-81ec-847d97c268e6', - axisMode: 'left', - textVisibility: true, - color: euiTheme.colors.danger, - iconPosition: 'right', - }, - ], - }, + ...(selectedTabId !== 'history' + ? [ + { + layerId: '34298f84-681e-4fa3-8107-d6facb32ed92', + layerType: 'referenceLine', + accessors: ['0a42b72b-cd5a-4d59-81ec-847d97c268e6'], + yConfig: [ + { + forAccessor: '0a42b72b-cd5a-4d59-81ec-847d97c268e6', + axisMode: 'left', + textVisibility: true, + color: euiTheme.colors.danger, + iconPosition: 'right', + }, + ], + }, + ] + : []), ...(!!alertTimeRange ? [ { diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/slo_overview_details.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/slo_overview_details.tsx index 14100474e00b3..5bfc07f3562bd 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/slo_overview_details.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/slo_overview_details.tsx @@ -79,9 +79,9 @@ export function SloOverviewDetails({ {tabs.map((tab, index) => ( {tab.label} diff --git a/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_historical_summary.ts b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_historical_summary.ts index 0627b1b50c923..95abc489d69de 100644 --- a/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_historical_summary.ts +++ b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_historical_summary.ts @@ -23,11 +23,16 @@ export interface UseFetchHistoricalSummaryResponse { export interface Params { sloList: SLOWithSummaryResponse[]; shouldRefetch?: boolean; + range?: { + from: string; + to: string; + }; } export function useFetchHistoricalSummary({ sloList = [], shouldRefetch, + range, }: Params): UseFetchHistoricalSummaryResponse { const { http } = useKibana().services; @@ -40,6 +45,7 @@ export function useFetchHistoricalSummary({ revision: slo.revision, objective: slo.objective, budgetingMethod: slo.budgetingMethod, + range, })); const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({ diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart.tsx index 552198aec1fa1..5b4794a3e9bcb 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart.tsx @@ -10,6 +10,8 @@ import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem, EuiStat } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { TimeBounds } from '../types'; +import { SloTabId } from './slo_details'; import { useKibana } from '../../../utils/kibana_react'; import { toDuration, toMinutes } from '../../../utils/slo/duration'; import { ChartData } from '../../../typings/slo'; @@ -33,9 +35,11 @@ export interface Props { data: ChartData[]; isLoading: boolean; slo: SLOWithSummaryResponse; + selectedTabId?: SloTabId; + onBrushed?: (timeBounds: TimeBounds) => void; } -export function ErrorBudgetChart({ data, isLoading, slo }: Props) { +export function ErrorBudgetChart({ data, isLoading, slo, selectedTabId, onBrushed }: Props) { const { uiSettings } = useKibana().services; const percentFormat = uiSettings.get('format:percent:defaultPattern'); const isSloFailed = slo.summary.status === 'DEGRADING' || slo.summary.status === 'VIOLATED'; @@ -53,23 +57,12 @@ export function ErrorBudgetChart({ data, isLoading, slo }: Props) { } return ( <> - - - - - {errorBudgetTimeRemainingFormatted ? ( + {selectedTabId !== 'history' && ( + - ) : null} - + {errorBudgetTimeRemainingFormatted ? ( + + + + ) : null} + + )} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx index 11034718c9100..b8ffb2f30a79e 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_chart_panel.tsx @@ -14,6 +14,8 @@ import { i18n } from '@kbn/i18n'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import React, { useState, useCallback } from 'react'; import { SaveModalDashboardProps } from '@kbn/presentation-util-plugin/public'; +import { TimeBounds } from '../types'; +import { SloTabId } from './slo_details'; import { useKibana } from '../../../utils/kibana_react'; import { ChartData } from '../../../typings/slo'; import { ErrorBudgetChart } from './error_budget_chart'; @@ -24,9 +26,11 @@ export interface Props { data: ChartData[]; isLoading: boolean; slo: SLOWithSummaryResponse; + selectedTabId: SloTabId; + onBrushed?: (timeBounds: TimeBounds) => void; } -export function ErrorBudgetChartPanel({ data, isLoading, slo }: Props) { +export function ErrorBudgetChartPanel({ data, isLoading, slo, selectedTabId, onBrushed }: Props) { const [isMouseOver, setIsMouseOver] = useState(false); const [isDashboardAttachmentReady, setDashboardAttachmentReady] = useState(false); @@ -81,9 +85,16 @@ export function ErrorBudgetChartPanel({ data, isLoading, slo }: Props) { showTitle={true} isMouseOver={isMouseOver} setDashboardAttachmentReady={setDashboardAttachmentReady} + selectedTabId={selectedTabId} /> - +
    {isDashboardAttachmentReady ? ( diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_header.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_header.tsx index b4cf6ae23cbb1..4a484d9df013f 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_header.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/error_budget_header.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { rollingTimeWindowTypeSchema, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { SloTabId } from './slo_details'; import { useKibana } from '../../../utils/kibana_react'; import { toDurationAdverbLabel, toDurationLabel } from '../../../utils/slo/labels'; @@ -19,6 +20,7 @@ interface Props { showTitle?: boolean; isMouseOver?: boolean; setDashboardAttachmentReady?: (value: boolean) => void; + selectedTabId?: SloTabId; } export function ErrorBudgetHeader({ @@ -26,6 +28,7 @@ export function ErrorBudgetHeader({ showTitle = true, isMouseOver, setDashboardAttachmentReady, + selectedTabId, }: Props) { const { executionContext } = useKibana().services; const executionContextName = executionContext.get().name; @@ -57,16 +60,18 @@ export function ErrorBudgetHeader({ )} - - - {rollingTimeWindowTypeSchema.is(slo.timeWindow.type) - ? i18n.translate('xpack.slo.sloDetails.errorBudgetChartPanel.duration', { - defaultMessage: 'Last {duration}', - values: { duration: toDurationLabel(slo.timeWindow.duration) }, - }) - : toDurationAdverbLabel(slo.timeWindow.duration)} - - + {selectedTabId !== 'history' && ( + + + {rollingTimeWindowTypeSchema.is(slo.timeWindow.type) + ? i18n.translate('xpack.slo.sloDetails.errorBudgetChartPanel.duration', { + defaultMessage: 'Last {duration}', + values: { duration: toDurationLabel(slo.timeWindow.duration) }, + }) + : toDurationAdverbLabel(slo.timeWindow.duration)} + + + )} ); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/events_chart_panel.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/events_chart_panel.tsx index e2f85a9d47e68..340d6ce465884 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/events_chart_panel.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/events_chart_panel.tsx @@ -36,6 +36,9 @@ import { max, min } from 'lodash'; import moment from 'moment'; import React, { useRef } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { TimeBounds } from '../types'; +import { getBrushData } from '../../../utils/slo/duration'; +import { SloTabId } from './slo_details'; import { useGetPreviewData } from '../../../hooks/use_get_preview_data'; import { useKibana } from '../../../utils/kibana_react'; import { COMPARATOR_MAPPING } from '../../slo_edit/constants'; @@ -48,9 +51,11 @@ export interface Props { start: number; end: number; }; + selectedTabId: SloTabId; + onBrushed?: (timeBounds: TimeBounds) => void; } -export function EventsChartPanel({ slo, range }: Props) { +export function EventsChartPanel({ slo, range, selectedTabId, onBrushed }: Props) { const { charts, uiSettings, discover } = useKibana().services; const { euiTheme } = useEuiTheme(); const baseTheme = charts.theme.useChartsBaseTheme(); @@ -157,13 +162,15 @@ export function EventsChartPanel({ slo, range }: Props) { {title} - - - {i18n.translate('xpack.slo.sloDetails.eventsChartPanel.duration', { - defaultMessage: 'Last 24h', - })} - - + {selectedTabId !== 'history' && ( + + + {i18n.translate('xpack.slo.sloDetails.eventsChartPanel.duration', { + defaultMessage: 'Last 24h', + })} + + + )} {showViewEventsLink && ( @@ -193,6 +200,7 @@ export function EventsChartPanel({ slo, range }: Props) { data={data || []} annotation={annotation} slo={slo} + onBrushed={onBrushed} /> ) : ( <> @@ -225,6 +233,9 @@ export function EventsChartPanel({ slo, range }: Props) { pointerUpdateDebounce={0} pointerUpdateTrigger={'x'} locale={i18n.getLocale()} + onBrushEnd={(brushArea) => { + onBrushed?.(getBrushData(brushArea)); + }} /> {annotation} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/historical_data_charts.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/historical_data_charts.tsx new file mode 100644 index 0000000000000..f2e096195f474 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/historical_data_charts.tsx @@ -0,0 +1,75 @@ +/* + * 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 { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { EuiFlexItem } from '@elastic/eui'; +import React from 'react'; +import { TimeBounds } from '../types'; +import { useFetchHistoricalSummary } from '../../../hooks/use_fetch_historical_summary'; +import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter'; +import { SloTabId } from './slo_details'; +import { SliChartPanel } from './sli_chart_panel'; +import { ErrorBudgetChartPanel } from './error_budget_chart_panel'; + +export interface Props { + slo: SLOWithSummaryResponse; + isAutoRefreshing: boolean; + selectedTabId: SloTabId; + range?: { + from: string; + to: string; + }; + onBrushed?: (timeBounds: TimeBounds) => void; +} +export function HistoricalDataCharts({ + slo, + range, + isAutoRefreshing, + selectedTabId, + onBrushed, +}: Props) { + const { data: historicalSummaries = [], isLoading: historicalSummaryLoading } = + useFetchHistoricalSummary({ + sloList: [slo], + shouldRefetch: isAutoRefreshing, + range, + }); + + const sloHistoricalSummary = historicalSummaries.find( + (historicalSummary) => + historicalSummary.sloId === slo.id && + historicalSummary.instanceId === (slo.instanceId ?? ALL_VALUE) + ); + + const errorBudgetBurnDownData = formatHistoricalData( + sloHistoricalSummary?.data, + 'error_budget_remaining' + ); + const historicalSliData = formatHistoricalData(sloHistoricalSummary?.data, 'sli_value'); + + return ( + <> + + + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/history/slo_details_history.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/history/slo_details_history.tsx new file mode 100644 index 0000000000000..0e20cb3960fbc --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/history/slo_details_history.tsx @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useMemo, useState } from 'react'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiSuperDatePicker, + OnTimeChangeProps, + OnRefreshProps, + EuiSpacer, +} from '@elastic/eui'; +import DateMath from '@kbn/datemath'; +import { useKibana } from '../../../../utils/kibana_react'; +import { HistoricalDataCharts } from '../historical_data_charts'; +import { useBurnRateOptions } from '../../hooks/use_burn_rate_options'; +import { SloTabId } from '../slo_details'; +import { BurnRates } from '../../../../components/slo/burn_rate/burn_rates'; +import { EventsChartPanel } from '../events_chart_panel'; +export interface Props { + slo: SLOWithSummaryResponse; + isAutoRefreshing: boolean; + selectedTabId: SloTabId; +} + +export function SLODetailsHistory({ slo, isAutoRefreshing, selectedTabId }: Props) { + const { uiSettings } = useKibana().services; + + const { burnRateOptions } = useBurnRateOptions(slo); + + const [start, setStart] = useState('now-30d'); + const [end, setEnd] = useState('now'); + + const onTimeChange = (val: OnTimeChangeProps) => { + setStart(val.start); + setEnd(val.end); + }; + + const onRefresh = (val: OnRefreshProps) => {}; + + const absRange = useMemo(() => { + return { + from: new Date(DateMath.parse(start)!.valueOf()), + to: new Date(DateMath.parse(end, { roundUp: true })!.valueOf()), + absoluteFrom: DateMath.parse(start)!.valueOf(), + absoluteTo: DateMath.parse(end, { roundUp: true })!.valueOf(), + }; + }, [start, end]); + + const onBrushed = useCallback(({ fromUtc, toUtc }) => { + setStart(fromUtc); + setEnd(toUtc); + }, []); + + return ( + <> + + + { + return { + start: from, + end: to, + label: display, + }; + })} + /> + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/sli_chart_panel.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/sli_chart_panel.tsx index 788303b43ffa1..b4b90ae4efab1 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/sli_chart_panel.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/sli_chart_panel.tsx @@ -10,6 +10,8 @@ import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; import { rollingTimeWindowTypeSchema, SLOWithSummaryResponse } from '@kbn/slo-schema'; import React from 'react'; +import { TimeBounds } from '../types'; +import { SloTabId } from './slo_details'; import { useKibana } from '../../../utils/kibana_react'; import { ChartData } from '../../../typings/slo'; import { toDurationAdverbLabel, toDurationLabel } from '../../../utils/slo/labels'; @@ -19,9 +21,11 @@ export interface Props { data: ChartData[]; isLoading: boolean; slo: SLOWithSummaryResponse; + selectedTabId: SloTabId; + onBrushed?: (timeBounds: TimeBounds) => void; } -export function SliChartPanel({ data, isLoading, slo }: Props) { +export function SliChartPanel({ data, isLoading, slo, selectedTabId, onBrushed }: Props) { const { uiSettings } = useKibana().services; const percentFormat = uiSettings.get('format:percent:defaultPattern'); @@ -41,41 +45,45 @@ export function SliChartPanel({ data, isLoading, slo }: Props) { - - - {rollingTimeWindowTypeSchema.is(slo.timeWindow.type) - ? i18n.translate('xpack.slo.sloDetails.sliHistoryChartPanel.duration', { - defaultMessage: 'Last {duration}', - values: { duration: toDurationLabel(slo.timeWindow.duration) }, - }) - : toDurationAdverbLabel(slo.timeWindow.duration)} - - + {selectedTabId !== 'history' && ( + + + {rollingTimeWindowTypeSchema.is(slo.timeWindow.type) + ? i18n.translate('xpack.slo.sloDetails.sliHistoryChartPanel.duration', { + defaultMessage: 'Last {duration}', + values: { duration: toDurationLabel(slo.timeWindow.duration) }, + }) + : toDurationAdverbLabel(slo.timeWindow.duration)} + + + )} - - - - - - - - + {selectedTabId !== 'history' && ( + + + + + + + + + )} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx index 01d62098e8802..cb5a1420dc06a 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_details.tsx @@ -5,71 +5,26 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, htmlIdGenerator } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import React, { useEffect, useState } from 'react'; -import { BurnRateOption, BurnRates } from '../../../components/slo/burn_rate/burn_rates'; -import { useFetchHistoricalSummary } from '../../../hooks/use_fetch_historical_summary'; -import { useFetchRulesForSlo } from '../../../hooks/use_fetch_rules_for_slo'; -import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter'; -import { ErrorBudgetChartPanel } from './error_budget_chart_panel'; +import { HistoricalDataCharts } from './historical_data_charts'; +import { useBurnRateOptions } from '../hooks/use_burn_rate_options'; +import { SLODetailsHistory } from './history/slo_details_history'; +import { BurnRates } from '../../../components/slo/burn_rate/burn_rates'; import { EventsChartPanel } from './events_chart_panel'; import { Overview } from './overview/overview'; -import { SliChartPanel } from './sli_chart_panel'; import { SloDetailsAlerts } from './slo_detail_alerts'; import { SloHealthCallout } from './slo_health_callout'; import { SloRemoteCallout } from './slo_remote_callout'; export const TAB_ID_URL_PARAM = 'tabId'; export const OVERVIEW_TAB_ID = 'overview'; +export const HISTORY_TAB_ID = 'history'; export const ALERTS_TAB_ID = 'alerts'; const DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000; -const DEFAULT_BURN_RATE_OPTIONS: BurnRateOption[] = [ - { - id: htmlIdGenerator()(), - label: i18n.translate('xpack.slo.burnRates.fromRange.label', { - defaultMessage: '{duration}h', - values: { duration: 1 }, - }), - windowName: 'CRITICAL', - threshold: 14.4, - duration: 1, - }, - { - id: htmlIdGenerator()(), - label: i18n.translate('xpack.slo.burnRates.fromRange.label', { - defaultMessage: '{duration}h', - values: { duration: 6 }, - }), - windowName: 'HIGH', - threshold: 6, - duration: 6, - }, - { - id: htmlIdGenerator()(), - label: i18n.translate('xpack.slo.burnRates.fromRange.label', { - defaultMessage: '{duration}h', - values: { duration: 24 }, - }), - windowName: 'MEDIUM', - threshold: 3, - duration: 24, - }, - { - id: htmlIdGenerator()(), - label: i18n.translate('xpack.slo.burnRates.fromRange.label', { - defaultMessage: '{duration}h', - values: { duration: 72 }, - }), - windowName: 'LOW', - threshold: 1, - duration: 72, - }, -]; - -export type SloTabId = typeof OVERVIEW_TAB_ID | typeof ALERTS_TAB_ID; +export type SloTabId = typeof OVERVIEW_TAB_ID | typeof ALERTS_TAB_ID | typeof HISTORY_TAB_ID; export interface Props { slo: SLOWithSummaryResponse; @@ -77,30 +32,7 @@ export interface Props { selectedTabId: SloTabId; } export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) { - const { data: rules } = useFetchRulesForSlo({ sloIds: [slo.id] }); - const burnRateOptions = - rules?.[slo.id]?.[0]?.params?.windows?.map((window) => ({ - id: htmlIdGenerator()(), - label: i18n.translate('xpack.slo.burnRates.fromRange.label', { - defaultMessage: '{duration}h', - values: { duration: window.longWindow.value }, - }), - windowName: window.actionGroup, - threshold: window.burnRateThreshold, - duration: window.longWindow.value, - })) ?? DEFAULT_BURN_RATE_OPTIONS; - - const { data: historicalSummaries = [], isLoading: historicalSummaryLoading } = - useFetchHistoricalSummary({ - sloList: [slo], - shouldRefetch: isAutoRefreshing, - }); - - const sloHistoricalSummary = historicalSummaries.find( - (historicalSummary) => - historicalSummary.sloId === slo.id && - historicalSummary.instanceId === (slo.instanceId ?? ALL_VALUE) - ); + const { burnRateOptions } = useBurnRateOptions(slo); const [range, setRange] = useState({ start: new Date().getTime() - DAY_IN_MILLISECONDS, @@ -118,12 +50,6 @@ export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) { return () => clearInterval(intervalId); }, [isAutoRefreshing]); - const errorBudgetBurnDownData = formatHistoricalData( - sloHistoricalSummary?.data, - 'error_budget_remaining' - ); - const historicalSliData = formatHistoricalData(sloHistoricalSummary?.data, 'sli_value'); - return selectedTabId === OVERVIEW_TAB_ID ? ( @@ -137,24 +63,26 @@ export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) { slo={slo} isAutoRefreshing={isAutoRefreshing} burnRateOptions={burnRateOptions} + selectedTabId={selectedTabId} /> + - - - - - - - + - ) : ( + ) : selectedTabId === ALERTS_TAB_ID ? ( + ) : ( + ); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/wide_chart.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/wide_chart.tsx index d737590b190a5..5d6d68ae7d892 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/wide_chart.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/wide_chart.tsx @@ -24,6 +24,8 @@ import moment from 'moment'; import React, { useRef } from 'react'; import { i18n } from '@kbn/i18n'; +import { getBrushData } from '../../../utils/slo/duration'; +import { TimeBounds } from '../types'; import { useKibana } from '../../../utils/kibana_react'; import { ChartData } from '../../../typings'; @@ -36,9 +38,10 @@ export interface Props { chart: ChartType; state: State; isLoading: boolean; + onBrushed?: (timeBounds: TimeBounds) => void; } -export function WideChart({ chart, data, id, isLoading, state }: Props) { +export function WideChart({ chart, data, id, isLoading, state, onBrushed }: Props) { const { charts, uiSettings } = useKibana().services; const baseTheme = charts.theme.useChartsBaseTheme(); const { euiTheme } = useEuiTheme(); @@ -63,7 +66,16 @@ export function WideChart({ chart, data, id, isLoading, state }: Props) { } + noResults={ + + } onPointerUpdate={handleCursorUpdate} externalPointerEvents={{ tooltip: { visible: true }, @@ -71,6 +83,9 @@ export function WideChart({ chart, data, id, isLoading, state }: Props) { pointerUpdateDebounce={0} pointerUpdateTrigger={'x'} locale={i18n.getLocale()} + onBrushEnd={(brushArea) => { + onBrushed?.(getBrushData(brushArea)); + }} /> { + const { data: rules } = useFetchRulesForSlo({ sloIds: [slo.id] }); + const burnRateOptions = + rules?.[slo.id]?.[0]?.params?.windows?.map((window) => ({ + id: htmlIdGenerator()(), + label: i18n.translate('xpack.slo.burnRates.fromRange.label', { + defaultMessage: '{duration}h', + values: { duration: window.longWindow.value }, + }), + windowName: window.actionGroup, + threshold: window.burnRateThreshold, + duration: window.longWindow.value, + })) ?? DEFAULT_BURN_RATE_OPTIONS; + + return { burnRateOptions }; +}; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_selected_tab.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_selected_tab.ts new file mode 100644 index 0000000000000..1b1ff616e9c09 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_selected_tab.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { SloDetailsPathParams } from '../types'; +import { + ALERTS_TAB_ID, + HISTORY_TAB_ID, + OVERVIEW_TAB_ID, + SloTabId, +} from '../components/slo_details'; + +export const useSelectedTab = () => { + const { tabId } = useParams(); + + const [selectedTabId, setSelectedTabId] = useState(() => { + return tabId && [OVERVIEW_TAB_ID, ALERTS_TAB_ID, HISTORY_TAB_ID].includes(tabId) + ? (tabId as SloTabId) + : OVERVIEW_TAB_ID; + }); + + useEffect(() => { + // update the url when the selected tab changes + if (tabId !== selectedTabId) { + setSelectedTabId(tabId as SloTabId); + } + }, [selectedTabId, tabId]); + + return { + selectedTabId: selectedTabId || OVERVIEW_TAB_ID, + setSelectedTabId, + }; +}; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_slo_details_tabs.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_slo_details_tabs.tsx index 5926d4f2cf406..8eb954d4b5771 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_slo_details_tabs.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/hooks/use_slo_details_tabs.tsx @@ -9,8 +9,15 @@ import { i18n } from '@kbn/i18n'; import { EuiNotificationBadge, EuiToolTip } from '@elastic/eui'; import React from 'react'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { paths } from '../../../../common/locators/paths'; +import { useKibana } from '../../../utils/kibana_react'; import { useFetchActiveAlerts } from '../../../hooks/use_fetch_active_alerts'; -import { ALERTS_TAB_ID, OVERVIEW_TAB_ID, SloTabId } from '../components/slo_details'; +import { + ALERTS_TAB_ID, + HISTORY_TAB_ID, + OVERVIEW_TAB_ID, + SloTabId, +} from '../components/slo_details'; export const useSloDetailsTabs = ({ slo, @@ -21,13 +28,15 @@ export const useSloDetailsTabs = ({ slo?: SLOWithSummaryResponse | null; isAutoRefreshing: boolean; selectedTabId: SloTabId; - setSelectedTabId: (val: SloTabId) => void; + setSelectedTabId?: (val: SloTabId) => void; }) => { const { data: activeAlerts } = useFetchActiveAlerts({ sloIdsAndInstanceIds: slo ? [[slo.id, slo.instanceId ?? ALL_VALUE]] : [], shouldRefetch: isAutoRefreshing, }); + const { basePath } = useKibana().services.http; + const isRemote = !!slo?.remote; const tabs = [ @@ -38,8 +47,47 @@ export const useSloDetailsTabs = ({ }), 'data-test-subj': 'overviewTab', isSelected: selectedTabId === OVERVIEW_TAB_ID, - onClick: () => setSelectedTabId(OVERVIEW_TAB_ID), + ...(setSelectedTabId + ? { + onClick: () => setSelectedTabId(OVERVIEW_TAB_ID), + } + : { + href: slo + ? `${basePath.get()}${paths.sloDetails( + slo.id, + slo.instanceId, + slo.remote?.remoteName, + OVERVIEW_TAB_ID + )}` + : undefined, + }), }, + ...(slo?.timeWindow.type === 'rolling' + ? [ + { + id: HISTORY_TAB_ID, + label: i18n.translate('xpack.slo.sloDetails.tab.historyLabel', { + defaultMessage: 'History', + }), + 'data-test-subj': 'historyTab', + isSelected: selectedTabId === HISTORY_TAB_ID, + ...(setSelectedTabId + ? { + onClick: () => setSelectedTabId(HISTORY_TAB_ID), + } + : { + href: slo + ? `${basePath.get()}${paths.sloDetails( + slo.id, + slo.instanceId, + slo.remote?.remoteName, + HISTORY_TAB_ID + )}` + : undefined, + }), + }, + ] + : []), { id: ALERTS_TAB_ID, label: isRemote ? ( @@ -63,7 +111,20 @@ export const useSloDetailsTabs = ({ {(activeAlerts && activeAlerts.get(slo)) ?? 0} ) : null, - onClick: () => setSelectedTabId(ALERTS_TAB_ID), + ...(setSelectedTabId + ? { + onClick: () => setSelectedTabId(ALERTS_TAB_ID), + } + : { + href: slo + ? `${basePath.get()}${paths.sloDetails( + slo.id, + slo.instanceId, + slo.remote?.remoteName, + ALERTS_TAB_ID + )}` + : undefined, + }), }, ]; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.test.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.test.tsx index cb8c8b37868d8..dd0b22e177701 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.test.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.test.tsx @@ -79,6 +79,7 @@ const mockKibana = () => { http: { basePath: { prepend: (url: string) => url, + get: () => 'http://localhost:5601', }, }, dataViews: { diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.tsx index 1fddae776ec01..3665bd68629f4 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/slo_details.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect, useState } from 'react'; -import { useLocation, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { useIsMutating } from '@tanstack/react-query'; import { EuiLoadingSpinner, EuiSkeletonText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -16,6 +16,7 @@ import type { SLOWithSummaryResponse } from '@kbn/slo-schema'; import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public'; import dedent from 'dedent'; +import { useSelectedTab } from './hooks/use_selected_tab'; import { HeaderMenu } from '../../components/header_menu/header_menu'; import { useSloDetailsTabs } from './hooks/use_slo_details_tabs'; import { useKibana } from '../../utils/kibana_react'; @@ -23,13 +24,7 @@ import { usePluginContext } from '../../hooks/use_plugin_context'; import { useFetchSloDetails } from '../../hooks/use_fetch_slo_details'; import { useLicense } from '../../hooks/use_license'; import PageNotFound from '../404'; -import { - ALERTS_TAB_ID, - OVERVIEW_TAB_ID, - SloDetails, - TAB_ID_URL_PARAM, - SloTabId, -} from './components/slo_details'; +import { SloDetails } from './components/slo_details'; import { HeaderTitle } from './components/header_title'; import { HeaderControl } from './components/header_control'; import { paths } from '../../../common/locators/paths'; @@ -45,7 +40,6 @@ export function SloDetailsPage() { observabilityAIAssistant, } = useKibana().services; const { ObservabilityPageTemplate } = usePluginContext(); - const { search } = useLocation(); const { hasAtLeast } = useLicense(); const hasRightLicense = hasAtLeast('platinum'); @@ -61,19 +55,12 @@ export function SloDetailsPage() { }); const isDeleting = Boolean(useIsMutating(['deleteSlo'])); - const [selectedTabId, setSelectedTabId] = useState(() => { - const searchParams = new URLSearchParams(search); - const urlTabId = searchParams.get(TAB_ID_URL_PARAM); - return urlTabId && [OVERVIEW_TAB_ID, ALERTS_TAB_ID].includes(urlTabId) - ? (urlTabId as SloTabId) - : OVERVIEW_TAB_ID; - }); + const { selectedTabId } = useSelectedTab(); const { tabs } = useSloDetailsTabs({ slo, isAutoRefreshing, selectedTabId, - setSelectedTabId, }); useBreadcrumbs(getBreadcrumbs(basePath, slo)); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/types.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/types.ts index 46aaa1b02f38b..7117cdd39db2c 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/types.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/types.ts @@ -7,4 +7,12 @@ export interface SloDetailsPathParams { sloId: string; + tabId?: string; +} + +export interface TimeBounds { + from: number; + to: number; + fromUtc: string; + toUtc: string; } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/common/good_bad_events_chart.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/common/good_bad_events_chart.tsx index f4d2b7aa2ceee..3f0e88b912ec2 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slos/components/common/good_bad_events_chart.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slos/components/common/good_bad_events_chart.tsx @@ -23,6 +23,8 @@ import { i18n } from '@kbn/i18n'; import { GetPreviewDataResponse, SLOWithSummaryResponse } from '@kbn/slo-schema'; import moment from 'moment'; import React, { useRef } from 'react'; +import { TimeBounds } from '../../../slo_details/types'; +import { getBrushData } from '../../../../utils/slo/duration'; import { useKibana } from '../../../../utils/kibana_react'; import { openInDiscover } from '../../../../utils/slo/get_discover_link'; @@ -32,6 +34,7 @@ export interface Props { annotation?: React.ReactNode; isLoading?: boolean; bottomTitle?: string; + onBrushed?: (timeBounds: TimeBounds) => void; } export function GoodBadEventsChart({ @@ -39,6 +42,7 @@ export function GoodBadEventsChart({ bottomTitle, data, slo, + onBrushed, isLoading = false, }: Props) { const { charts, uiSettings, discover } = useKibana().services; @@ -97,7 +101,16 @@ export function GoodBadEventsChart({ showLegend={true} showLegendExtra={false} legendPosition={Position.Left} - noResults={} + noResults={ + + } onPointerUpdate={handleCursorUpdate} externalPointerEvents={{ tooltip: { visible: true }, @@ -106,6 +119,9 @@ export function GoodBadEventsChart({ pointerUpdateTrigger={'x'} locale={i18n.getLocale()} onElementClick={barClickHandler as ElementClickListener} + onBrushEnd={(brushArea) => { + onBrushed?.(getBrushData(brushArea)); + }} /> {annotation} { const dateRangeBySlo = params.list.reduce>( - (acc, { sloId, timeWindow }) => { - acc[sloId] = getDateRange(timeWindow); + (acc, { sloId, timeWindow, range }) => { + acc[sloId] = range ?? getDateRange(timeWindow); return acc; }, {} @@ -272,6 +272,13 @@ function handleResultForRollingAndTimeslices( }); } +export const getEsDateRange = (dateRange: DateRange) => { + return { + gte: typeof dateRange.from === 'string' ? dateRange.from : dateRange.from.toISOString(), + lte: typeof dateRange.to === 'string' ? dateRange.to : dateRange.to.toISOString(), + }; +}; + function generateSearchQuery({ sloId, groupBy, @@ -309,10 +316,7 @@ function generateSearchQuery({ { term: { 'slo.revision': revision } }, { range: { - '@timestamp': { - gte: dateRange.from.toISOString(), - lte: dateRange.to.toISOString(), - }, + '@timestamp': getEsDateRange(dateRange), }, }, ...extraFilterByInstanceId, @@ -325,7 +329,7 @@ function generateSearchQuery({ field: '@timestamp', fixed_interval: fixedInterval, extended_bounds: { - min: dateRange.from.toISOString(), + min: typeof dateRange.from === 'string' ? dateRange.from : dateRange.from.toISOString(), max: 'now/d', }, }, diff --git a/x-pack/plugins/observability_solution/slo/server/services/summary_client.test.ts b/x-pack/plugins/observability_solution/slo/server/services/summary_client.test.ts index ec735058b1bd3..584aba75e22ff 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/summary_client.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/summary_client.test.ts @@ -58,7 +58,7 @@ describe('SummaryClient', () => { { term: { 'slo.revision': slo.revision } }, { range: { - '@timestamp': { gte: expect.anything(), lt: expect.anything() }, + '@timestamp': { gte: expect.anything(), lte: expect.anything() }, }, }, ], @@ -94,7 +94,7 @@ describe('SummaryClient', () => { range: { '@timestamp': { gte: expect.anything(), - lt: expect.anything(), + lte: expect.anything(), }, }, }, @@ -136,7 +136,7 @@ describe('SummaryClient', () => { { term: { 'slo.revision': slo.revision } }, { range: { - '@timestamp': { gte: expect.anything(), lt: expect.anything() }, + '@timestamp': { gte: expect.anything(), lte: expect.anything() }, }, }, ], @@ -188,7 +188,7 @@ describe('SummaryClient', () => { range: { '@timestamp': { gte: expect.anything(), - lt: expect.anything(), + lte: expect.anything(), }, }, }, diff --git a/x-pack/plugins/observability_solution/slo/server/services/summary_client.ts b/x-pack/plugins/observability_solution/slo/server/services/summary_client.ts index 4a41db114c9cf..5e5ee5a7228a0 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/summary_client.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/summary_client.ts @@ -16,6 +16,7 @@ import { occurrencesBudgetingMethodSchema, timeslicesBudgetingMethodSchema, } from '@kbn/slo-schema'; +import { getEsDateRange } from './historical_summary_client'; import { SLO_DESTINATION_INDEX_PATTERN } from '../../common/constants'; import { Groupings, Meta, SLODefinition, Summary } from '../domain/models'; import { computeSLI, computeSummaryStatus, toErrorBudget } from '../domain/services'; @@ -75,7 +76,7 @@ export class DefaultSummaryClient implements SummaryClient { { term: { 'slo.revision': slo.revision } }, { range: { - '@timestamp': { gte: dateRange.from.toISOString(), lt: dateRange.to.toISOString() }, + '@timestamp': getEsDateRange(dateRange), }, }, ...instanceIdFilter, diff --git a/x-pack/plugins/observability_solution/slo/tsconfig.json b/x-pack/plugins/observability_solution/slo/tsconfig.json index b8a9c1d5e21b2..70ff3d26f591f 100644 --- a/x-pack/plugins/observability_solution/slo/tsconfig.json +++ b/x-pack/plugins/observability_solution/slo/tsconfig.json @@ -97,6 +97,7 @@ "@kbn/data-view-field-editor-plugin", "@kbn/securitysolution-io-ts-utils", "@kbn/core-elasticsearch-server-mocks", + "@kbn/datemath", "@kbn/presentation-containers", ] } From d887763f0ee08257db8a6838cdab94f075b95619 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 1 May 2024 14:38:49 +0200 Subject: [PATCH 093/104] Revert "[ES|QL] Fetch the query columns utils (#181969)" (#182238) This reverts commit 4262afe43c4e9158beabc456e9c92f7f26f3b359. --- packages/kbn-esql-utils/index.ts | 1 - packages/kbn-esql-utils/src/index.ts | 1 - .../src/utils/run_query_utils.ts | 52 ----------------- packages/kbn-esql-utils/tsconfig.json | 4 -- .../shared/edit_on_the_fly/helpers.test.ts | 57 ++++++++++--------- .../shared/edit_on_the_fly/helpers.ts | 38 +++++++++---- .../public/editor_frame_service/mocks.tsx | 2 +- .../open_lens_config/create_action_helpers.ts | 20 ++++--- 8 files changed, 68 insertions(+), 107 deletions(-) delete mode 100644 packages/kbn-esql-utils/src/utils/run_query_utils.ts diff --git a/packages/kbn-esql-utils/index.ts b/packages/kbn-esql-utils/index.ts index 9272eddb4debd..0d04f40b85612 100644 --- a/packages/kbn-esql-utils/index.ts +++ b/packages/kbn-esql-utils/index.ts @@ -17,7 +17,6 @@ export { getESQLWithSafeLimit, appendToESQLQuery, TextBasedLanguages, - getESQLQueryColumns, } from './src'; export { ESQL_LATEST_VERSION } from './constants'; diff --git a/packages/kbn-esql-utils/src/index.ts b/packages/kbn-esql-utils/src/index.ts index a637ab0574d5e..92a39a4a6f793 100644 --- a/packages/kbn-esql-utils/src/index.ts +++ b/packages/kbn-esql-utils/src/index.ts @@ -17,4 +17,3 @@ export { removeDropCommandsFromESQLQuery, } from './utils/query_parsing_helpers'; export { appendToESQLQuery } from './utils/append_to_query'; -export { getESQLQueryColumns } from './utils/run_query_utils'; diff --git a/packages/kbn-esql-utils/src/utils/run_query_utils.ts b/packages/kbn-esql-utils/src/utils/run_query_utils.ts deleted file mode 100644 index 1512c86b2b8bf..0000000000000 --- a/packages/kbn-esql-utils/src/utils/run_query_utils.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { DatatableColumn } from '@kbn/expressions-plugin/common'; -import type { ISearchStart } from '@kbn/data-plugin/public'; -import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; -import type { ESQLSearchReponse } from '@kbn/es-types'; -import { lastValueFrom } from 'rxjs'; -import { ESQL_LATEST_VERSION } from '../../constants'; - -export async function getESQLQueryColumns({ - esqlQuery, - search, - signal, -}: { - esqlQuery: string; - search: ISearchStart; - signal?: AbortSignal; -}): Promise { - const response = await lastValueFrom( - search.search( - { - params: { - query: `${esqlQuery} | limit 0`, - version: ESQL_LATEST_VERSION, - }, - }, - { - abortSignal: signal, - strategy: 'esql_async', - } - ) - ); - - const columns = - (response.rawResponse as unknown as ESQLSearchReponse).columns?.map(({ name, type }) => { - const kibanaType = esFieldTypeToKibanaFieldType(type); - const column = { - id: name, - name, - meta: { type: kibanaType, esType: type }, - } as DatatableColumn; - - return column; - }) ?? []; - - return columns; -} diff --git a/packages/kbn-esql-utils/tsconfig.json b/packages/kbn-esql-utils/tsconfig.json index 1185d03b56448..5a494e9929d7b 100644 --- a/packages/kbn-esql-utils/tsconfig.json +++ b/packages/kbn-esql-utils/tsconfig.json @@ -17,12 +17,8 @@ ], "kbn_references": [ "@kbn/data-views-plugin", - "@kbn/data-plugin", "@kbn/crypto-browser", "@kbn/data-view-utils", "@kbn/esql-ast", - "@kbn/expressions-plugin", - "@kbn/field-types", - "@kbn/es-types", ] } diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts index fcdb83a978f6a..57638b61db1a9 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts @@ -5,7 +5,7 @@ * 2.0. */ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { getESQLQueryColumns } from '@kbn/esql-utils'; +import { fetchFieldsFromESQL } from '@kbn/text-based-editor'; import type { LensPluginStartDependencies } from '../../../plugin'; import { createMockStartDependencies } from '../../../editor_frame_service/mocks'; import { @@ -18,44 +18,45 @@ import { suggestionsApi } from '../../../lens_suggestions_api'; import { getSuggestions } from './helpers'; const mockSuggestionApi = suggestionsApi as jest.Mock; -const mockFetchData = getESQLQueryColumns as jest.Mock; +const mockFetchData = fetchFieldsFromESQL as jest.Mock; jest.mock('../../../lens_suggestions_api', () => ({ suggestionsApi: jest.fn(() => mockAllSuggestions), })); -jest.mock('@kbn/esql-utils', () => { - return { - getESQLQueryColumns: jest.fn().mockResolvedValue(() => [ - { - name: '@timestamp', - id: '@timestamp', - meta: { - type: 'date', +jest.mock('@kbn/text-based-editor', () => ({ + fetchFieldsFromESQL: jest.fn(() => { + return { + columns: [ + { + name: '@timestamp', + id: '@timestamp', + meta: { + type: 'date', + }, }, - }, - { - name: 'bytes', - id: 'bytes', - meta: { - type: 'number', + { + name: 'bytes', + id: 'bytes', + meta: { + type: 'number', + }, }, - }, - { - name: 'memory', - id: 'memory', - meta: { - type: 'number', + { + name: 'memory', + id: 'memory', + meta: { + type: 'number', + }, }, - }, - ]), - getIndexPatternFromESQLQuery: jest.fn().mockReturnValue('index1'), - }; -}); + ], + }; + }), +})); describe('getSuggestions', () => { const query = { - esql: 'from index1 | limit 10 | stats average = avg(bytes)', + esql: 'from index1 | limit 10 | stats average = avg(bytes', }; const mockStartDependencies = createMockStartDependencies() as unknown as LensPluginStartDependencies; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts index 9ab8b5fc05aef..803fcbf169935 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts @@ -4,20 +4,39 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { - getIndexPatternFromSQLQuery, - getIndexPatternFromESQLQuery, - getESQLAdHocDataview, - getESQLQueryColumns, -} from '@kbn/esql-utils'; +import { getIndexPatternFromSQLQuery, getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; import type { AggregateQuery } from '@kbn/es-query'; +import { getESQLAdHocDataview } from '@kbn/esql-utils'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; +import { fetchFieldsFromESQL } from '@kbn/text-based-editor'; import type { DataViewSpec } from '@kbn/data-views-plugin/public'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; import type { LensPluginStartDependencies } from '../../../plugin'; import type { DatasourceMap, VisualizationMap } from '../../../types'; import { suggestionsApi } from '../../../lens_suggestions_api'; +export const getQueryColumns = async ( + query: AggregateQuery, + deps: LensPluginStartDependencies, + abortController?: AbortController +) => { + // Fetching only columns for ES|QL for performance reasons with limit 0 + // Important note: ES doesnt return the warnings for 0 limit, + // I am skipping them in favor of performance now + // but we should think another way to get them (from Lens embeddable or store) + const performantQuery = { ...query }; + if ('esql' in performantQuery && performantQuery.esql) { + performantQuery.esql = `${performantQuery.esql} | limit 0`; + } + const table = await fetchFieldsFromESQL( + performantQuery, + deps.expressions, + undefined, + abortController + ); + return table?.columns; +}; + export const getSuggestions = async ( query: AggregateQuery, deps: LensPluginStartDependencies, @@ -46,12 +65,7 @@ export const getSuggestions = async ( if (dataView.fields.getByName('@timestamp')?.type === 'date' && !dataViewSpec) { dataView.timeFieldName = '@timestamp'; } - - const columns = await getESQLQueryColumns({ - esqlQuery: 'esql' in query ? query.esql : '', - search: deps.data.search, - signal: abortController?.signal, - }); + const columns = await getQueryColumns(query, deps, abortController); const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', diff --git a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx index eacbbc079413d..4513e0f4bffd4 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx @@ -55,7 +55,7 @@ export function createMockSetupDependencies() { export function createMockStartDependencies() { return { - data: dataPluginMock.createStartContract(), + data: dataPluginMock.createSetupContract(), embeddable: embeddablePluginMock.createStartContract(), expressions: expressionsPluginMock.createStartContract(), charts: chartPluginMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts index 0d6f85e7703ad..3e77f8979a872 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts @@ -6,13 +6,13 @@ */ import { createGetterSetter } from '@kbn/kibana-utils-plugin/common'; import type { CoreStart } from '@kbn/core/public'; -import { getESQLQueryColumns } from '@kbn/esql-utils'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { PresentationContainer } from '@kbn/presentation-containers'; import { getESQLAdHocDataview, getIndexForESQLQuery } from '@kbn/esql-utils'; import type { Datasource, Visualization } from '../../types'; import type { LensPluginStartDependencies } from '../../plugin'; +import { fetchDataFromAggregateQuery } from '../../datasources/text_based/fetch_data_from_aggregate_query'; import { suggestionsApi } from '../../lens_suggestions_api'; import { generateId } from '../../id_generator'; import { executeEditAction } from './edit_action_helpers'; @@ -66,17 +66,21 @@ export async function executeCreateAction({ // so we are requesting them with limit 0 // this is much more performant than requesting // all the table - const abortController = new AbortController(); - const columns = await getESQLQueryColumns({ - esqlQuery: `from ${defaultIndex}`, - search: deps.data.search, - signal: abortController.signal, - }); + const performantQuery = { + esql: `from ${defaultIndex} | limit 0`, + }; + + const table = await fetchDataFromAggregateQuery( + performantQuery, + dataView, + deps.data, + deps.expressions + ); const context = { dataViewSpec: dataView.toSpec(), fieldName: '', - textBasedColumns: columns, + textBasedColumns: table?.columns, query: defaultEsqlQuery, }; From 639938c09849b70991a6d9c95b78a96fc6bc4c40 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 14:39:03 +0100 Subject: [PATCH 094/104] skip flaky suite (#182136) --- test/functional/apps/visualize/group5/_tsvb_time_series.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/visualize/group5/_tsvb_time_series.ts b/test/functional/apps/visualize/group5/_tsvb_time_series.ts index dbddadbe4a746..fb0309f8cec70 100644 --- a/test/functional/apps/visualize/group5/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/group5/_tsvb_time_series.ts @@ -145,7 +145,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(actualCountMin).to.be('3 hours'); }); - describe('Dark mode', () => { + // FLAKY: https://github.com/elastic/kibana/issues/182136 + describe.skip('Dark mode', () => { before(async () => { await kibanaServer.uiSettings.update({ 'theme:darkMode': true, From 188493afeead9d00ae793d37f780b609e16efa68 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 14:41:15 +0100 Subject: [PATCH 095/104] skip flaky suite (#177142) --- x-pack/test/monitoring_api_integration/apis/apm/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/monitoring_api_integration/apis/apm/index.ts b/x-pack/test/monitoring_api_integration/apis/apm/index.ts index 0171da7e6b83a..ddb2109173f12 100644 --- a/x-pack/test/monitoring_api_integration/apis/apm/index.ts +++ b/x-pack/test/monitoring_api_integration/apis/apm/index.ts @@ -9,7 +9,8 @@ import { FtrProviderContext } from '../../../api_integration/ftr_provider_contex import { installPackage } from '../../packages'; export default function ({ loadTestFile, getService }: FtrProviderContext) { - describe('APM', () => { + // FLAKY: https://github.com/elastic/kibana/issues/177142 + describe.skip('APM', () => { before(() => installPackage(getService('supertest'), 'beat')); loadTestFile(require.resolve('./overview')); From f16c40e08338879a5da08b425f118cdc2750bb32 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 1 May 2024 14:42:29 +0100 Subject: [PATCH 096/104] skip flaky suite (#181955) --- test/functional/apps/dashboard/group1/embeddable_data_grid.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/dashboard/group1/embeddable_data_grid.ts b/test/functional/apps/dashboard/group1/embeddable_data_grid.ts index 71da8fadea4af..010644b1d2029 100644 --- a/test/functional/apps/dashboard/group1/embeddable_data_grid.ts +++ b/test/functional/apps/dashboard/group1/embeddable_data_grid.ts @@ -19,7 +19,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const dataGrid = getService('dataGrid'); - describe('dashboard embeddable data grid', () => { + // FLAKY: https://github.com/elastic/kibana/issues/181955 + describe.skip('dashboard embeddable data grid', () => { before(async () => { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/dashboard/current/data'); From 0c8c4c1b1702a0a3b0a1b152cb70cc1d3f3d68ba Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 1 May 2024 15:51:53 +0200 Subject: [PATCH 097/104] [Obs AI Assistant] Remove unneeded plugin references (#182116) No code changes, just moving stuff around so the plugin can more easily by required by other plugins. --- .../common/index.ts | 2 + .../public/components/chat/types.ts | 3 +- .../public/types.ts | 2 - .../server/index.ts | 2 + .../observability_ai_assistant/tsconfig.json | 43 +++++------- .../scripts/evaluation/.eslintrc.json | 0 .../scripts/evaluation/README.md | 0 .../evaluation/alert_templates/templates.ts | 0 .../scripts/evaluation/cli.ts | 0 .../scripts/evaluation/evaluation.ts | 2 +- .../scripts/evaluation/get_service_urls.ts | 0 .../scripts/evaluation/index.js | 0 .../scripts/evaluation/kibana_client.ts | 40 ++++++----- .../scripts/evaluation/read_kibana_config.ts | 0 .../evaluation/scenarios/alerts/index.spec.ts | 2 +- .../evaluation/scenarios/apm/index.spec.ts | 2 +- .../scenarios/elasticsearch/index.spec.ts | 2 +- .../evaluation/scenarios/esql/index.spec.ts | 0 .../evaluation/scenarios/kb/index.spec.ts | 2 +- .../scripts/evaluation/services/index.ts | 0 .../scripts/evaluation/setup_synthtrace.ts | 0 .../scripts/evaluation/types.ts | 2 +- .../load_esql_docs/extract_sections.ts | 0 .../load_esql_docs/format_esql_examples.ts | 0 .../scripts/load_esql_docs/index.js | 0 .../scripts/load_esql_docs/load_esql_docs.ts | 0 .../tsconfig.json | 66 ++++++++++--------- 27 files changed, 87 insertions(+), 83 deletions(-) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/.eslintrc.json (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/README.md (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/alert_templates/templates.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/cli.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/evaluation.ts (99%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/get_service_urls.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/index.js (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/kibana_client.ts (95%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/read_kibana_config.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/scenarios/alerts/index.spec.ts (98%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/scenarios/apm/index.spec.ts (98%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/scenarios/elasticsearch/index.spec.ts (98%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/scenarios/esql/index.spec.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/scenarios/kb/index.spec.ts (95%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/services/index.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/setup_synthtrace.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/evaluation/types.ts (92%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/load_esql_docs/extract_sections.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/load_esql_docs/format_esql_examples.ts (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/load_esql_docs/index.js (100%) rename x-pack/plugins/observability_solution/{observability_ai_assistant => observability_ai_assistant_app}/scripts/load_esql_docs/load_esql_docs.ts (100%) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts index 66876bfe26085..dc8a9d46a7a06 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts @@ -43,6 +43,8 @@ export { aiAssistantSimulatedFunctionCalling, } from './ui_settings/settings_keys'; +export { concatenateChatCompletionChunks } from './utils/concatenate_chat_completion_chunks'; + export { DEFAULT_LANGUAGE_OPTION, LANGUAGE_OPTIONS } from './ui_settings/language_options'; export { isSupportedConnectorType } from './connectors'; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/chat/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/chat/types.ts index 1440be7723b4b..2151f65b95f80 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/chat/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/chat/types.ts @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; type ChatActionClickPayloadBase = { type: TType; @@ -14,7 +13,7 @@ type ChatActionClickPayloadExecuteEsql = ChatActionClickPayloadBase< | ChatActionClickType.executeEsqlQuery | ChatActionClickType.visualizeEsqlQuery | ChatActionClickType.updateVisualization, - { query: string; userOverrides?: TypedLensByValueInput } + { query: string; userOverrides?: unknown } >; export type ChatActionClickPayload = ChatActionClickPayloadExecuteEsql; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts index 69a1a6821197b..025edb80227a9 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts @@ -7,7 +7,6 @@ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; -import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; import type { Observable } from 'rxjs'; import type { MessageAddEvent, @@ -108,7 +107,6 @@ export interface ObservabilityAIAssistantPluginSetupDependencies { export interface ObservabilityAIAssistantPluginStartDependencies { licensing: LicensingPluginStart; security: SecurityPluginStart; - triggersActionsUi: TriggersAndActionsUIPublicPluginStart; } export interface ObservabilityAIAssistantPublicSetup {} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts index b67a9ab0a477c..344d46f557782 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts @@ -24,6 +24,8 @@ export { aiAssistantSimulatedFunctionCalling, } from '../common'; +export { streamIntoObservable } from './service/util/stream_into_observable'; + export const config: PluginConfigDescriptor = { deprecations: ({ unusedFromRoot }) => [ unusedFromRoot('xpack.observability.aiAssistant.enabled', { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json index b3fe0f8c8f6fc..0db746a4ab80c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json @@ -13,41 +13,32 @@ "server/**/*" ], "kbn_references": [ + "@kbn/i18n", + "@kbn/core-analytics-browser", + "@kbn/analytics-client", + "@kbn/logging", "@kbn/core", - "@kbn/actions-plugin", - "@kbn/utility-types", "@kbn/server-route-repository", - "@kbn/logging", - "@kbn/config-schema", - "@kbn/security-plugin", - "@kbn/i18n", - "@kbn/spaces-plugin", + "@kbn/licensing-plugin", + "@kbn/actions-plugin", + "@kbn/std", + "@kbn/kibana-utils-plugin", "@kbn/kibana-react-plugin", "@kbn/shared-ux-utility", - "@kbn/alerting-plugin", - "@kbn/kibana-utils-plugin", + "@kbn/security-plugin", + "@kbn/utility-types-jest", + "@kbn/config-schema", "@kbn/io-ts-utils", - "@kbn/std", - "@kbn/alerting-plugin", - "@kbn/features-plugin", - "@kbn/lens-plugin", + "@kbn/utility-types", "@kbn/data-views-plugin", - "@kbn/task-manager-plugin", "@kbn/rule-registry-plugin", - "@kbn/licensing-plugin", - "@kbn/utility-types-jest", - "@kbn/analytics-client", - "@kbn/tooling-log", - "@kbn/babel-register", - "@kbn/dev-cli-runner", - "@kbn/core-analytics-browser", - "@kbn/expect", - "@kbn/apm-synthtrace-client", - "@kbn/apm-synthtrace", + "@kbn/alerting-plugin", + "@kbn/spaces-plugin", + "@kbn/task-manager-plugin", + "@kbn/apm-utils", + "@kbn/features-plugin", "@kbn/cloud-plugin", "@kbn/serverless", - "@kbn/triggers-actions-ui-plugin", - "@kbn/apm-utils" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/.eslintrc.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/.eslintrc.json similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/.eslintrc.json rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/.eslintrc.json diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/README.md b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/README.md similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/README.md rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/README.md diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/alert_templates/templates.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/alert_templates/templates.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/alert_templates/templates.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/alert_templates/templates.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/cli.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/cli.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/cli.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/cli.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/evaluation.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/evaluation.ts similarity index 99% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/evaluation.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/evaluation.ts index 650a5cedceaa8..738285ffefc6e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/evaluation.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/evaluation.ts @@ -19,7 +19,7 @@ import * as table from 'table'; import { TableUserConfig } from 'table'; import { format, parse } from 'url'; import { ToolingLog } from '@kbn/tooling-log'; -import { MessageRole } from '../../common'; +import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { EvaluateWith, options } from './cli'; import { getServiceUrls } from './get_service_urls'; import { KibanaClient } from './kibana_client'; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/get_service_urls.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/get_service_urls.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/get_service_urls.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/get_service_urls.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/index.js b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/index.js similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/index.js rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/index.js diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/kibana_client.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts similarity index 95% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/kibana_client.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts index 7604b7bca4a17..364ef1c44a48f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/kibana_client.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts @@ -5,6 +5,29 @@ * 2.0. */ +import { + BufferFlushEvent, + ChatCompletionChunkEvent, + ChatCompletionErrorCode, + ChatCompletionErrorEvent, + concatenateChatCompletionChunks, + ConversationCreateEvent, + FunctionDefinition, + isChatCompletionError, + MessageAddEvent, + StreamingChatResponseEvent, + StreamingChatResponseEventType, +} from '@kbn/observability-ai-assistant-plugin/common'; +import type { ObservabilityAIAssistantScreenContext } from '@kbn/observability-ai-assistant-plugin/common/types'; +import { throwSerializedChatCompletionErrors } from '@kbn/observability-ai-assistant-plugin/common/utils/throw_serialized_chat_completion_errors'; +import { + APIReturnType, + isSupportedConnectorType, + Message, + MessageRole, + ObservabilityAIAssistantAPIClientRequestParamsOf, +} from '@kbn/observability-ai-assistant-plugin/public'; +import { streamIntoObservable } from '@kbn/observability-ai-assistant-plugin/server'; import { ToolingLog } from '@kbn/tooling-log'; import axios, { AxiosInstance, AxiosResponse, isAxiosError } from 'axios'; import { isArray, pick, remove } from 'lodash'; @@ -24,23 +47,6 @@ import { } from 'rxjs'; import { format, parse, UrlObject } from 'url'; import { inspect } from 'util'; -import { ChatCompletionErrorCode, isChatCompletionError, Message, MessageRole } from '../../common'; -import { isSupportedConnectorType } from '../../common/connectors'; -import { - BufferFlushEvent, - ChatCompletionChunkEvent, - ChatCompletionErrorEvent, - ConversationCreateEvent, - MessageAddEvent, - StreamingChatResponseEvent, - StreamingChatResponseEventType, -} from '../../common/conversation_complete'; -import { FunctionDefinition } from '../../common/functions/types'; -import { ObservabilityAIAssistantScreenContext } from '../../common/types'; -import { concatenateChatCompletionChunks } from '../../common/utils/concatenate_chat_completion_chunks'; -import { throwSerializedChatCompletionErrors } from '../../common/utils/throw_serialized_chat_completion_errors'; -import { APIReturnType, ObservabilityAIAssistantAPIClientRequestParamsOf } from '../../public'; -import { streamIntoObservable } from '../../server/service/util/stream_into_observable'; import { EvaluationResult } from './types'; // eslint-disable-next-line spaced-comment diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/read_kibana_config.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/read_kibana_config.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/read_kibana_config.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/read_kibana_config.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/alerts/index.spec.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/alerts/index.spec.ts similarity index 98% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/alerts/index.spec.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/alerts/index.spec.ts index 304851e2b1e61..b746ea8d4645f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/alerts/index.spec.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/alerts/index.spec.ts @@ -11,12 +11,12 @@ import expect from '@kbn/expect'; import { RuleResponse } from '@kbn/alerting-plugin/common/routes/rule/response/types/v1'; import moment from 'moment'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { chatClient, kibanaClient, synthtraceEsClients, logger } from '../../services'; import { apmTransactionRateAIAssistant, customThresholdAIAssistantLogCount, } from '../../alert_templates/templates'; -import { MessageRole } from '../../../../common'; describe('alert function', () => { const ruleIds: any[] = []; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/apm/index.spec.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/apm/index.spec.ts similarity index 98% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/apm/index.spec.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/apm/index.spec.ts index 6d715dd911dbf..8668b3b984528 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/apm/index.spec.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/apm/index.spec.ts @@ -11,8 +11,8 @@ import expect from '@kbn/expect'; import moment from 'moment'; import { apm, timerange, serviceMap } from '@kbn/apm-synthtrace-client'; import { RuleResponse } from '@kbn/alerting-plugin/common/routes/rule/response/types/v1'; +import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { chatClient, kibanaClient, synthtraceEsClients } from '../../services'; -import { MessageRole } from '../../../../common'; import { apmErrorCountAIAssistant } from '../../alert_templates/templates'; describe('apm', () => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/elasticsearch/index.spec.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/elasticsearch/index.spec.ts similarity index 98% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/elasticsearch/index.spec.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/elasticsearch/index.spec.ts index 20f78d487a4bf..b79d55d81daf2 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/elasticsearch/index.spec.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/elasticsearch/index.spec.ts @@ -8,8 +8,8 @@ /// import expect from '@kbn/expect'; +import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { chatClient, esClient } from '../../services'; -import { MessageRole } from '../../../../common'; describe('elasticsearch functions', () => { describe('health', () => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/esql/index.spec.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/esql/index.spec.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/esql/index.spec.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/esql/index.spec.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/kb/index.spec.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/kb/index.spec.ts similarity index 95% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/kb/index.spec.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/kb/index.spec.ts index 4460fffda8355..d32dcae5ac8b5 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/scenarios/kb/index.spec.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/scenarios/kb/index.spec.ts @@ -8,8 +8,8 @@ /// import expect from '@kbn/expect'; +import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { chatClient, esClient } from '../../services'; -import { MessageRole } from '../../../../common'; describe('kb functions', () => { it('summarizes and recalls information', async () => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/services/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/services/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/services/index.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/services/index.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/setup_synthtrace.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/setup_synthtrace.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/setup_synthtrace.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/setup_synthtrace.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/types.ts similarity index 92% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/types.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/types.ts index 20000b322d911..2e9545550840f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/evaluation/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/types.ts @@ -6,7 +6,7 @@ */ import type { Client } from '@elastic/elasticsearch'; -import { Message } from '../../common'; +import type { Message } from '@kbn/observability-ai-assistant-plugin/public'; import { KibanaClient } from './kibana_client'; import { SynthtraceEsClients } from './setup_synthtrace'; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/extract_sections.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/extract_sections.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/extract_sections.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/extract_sections.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/format_esql_examples.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/format_esql_examples.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/format_esql_examples.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/format_esql_examples.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/index.js b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/index.js similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/index.js rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/index.js diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/load_esql_docs.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/load_esql_docs.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant/scripts/load_esql_docs/load_esql_docs.ts rename to x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/load_esql_docs.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json index 8c7224647ce24..5b32c8ce5aa7c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json @@ -13,55 +13,61 @@ "server/**/*" ], "kbn_references": [ - "@kbn/core", - "@kbn/logging", - "@kbn/config-schema", - "@kbn/security-plugin", - "@kbn/i18n", - "@kbn/kibana-react-plugin", - "@kbn/observability-shared-plugin", - "@kbn/lens-embeddable-utils", - "@kbn/field-formats-plugin", - "@kbn/lens-plugin", - "@kbn/data-views-plugin", - "@kbn/es-query", - "@kbn/rule-registry-plugin", - "@kbn/licensing-plugin", - "@kbn/share-plugin", - "@kbn/ui-actions-plugin", - "@kbn/expressions-plugin", - "@kbn/visualization-utils", - "@kbn/field-types", "@kbn/es-types", - "@kbn/esql-utils", "@kbn/observability-ai-assistant-plugin", + "@kbn/field-formats-plugin", + "@kbn/core", "@kbn/typed-react-router-config", + "@kbn/i18n", + "@kbn/management-settings-ids", + "@kbn/security-plugin", "@kbn/ui-theme", "@kbn/actions-plugin", "@kbn/user-profile-components", - "@kbn/i18n-react", - "@kbn/triggers-actions-ui-plugin", "@kbn/core-http-browser", + "@kbn/triggers-actions-ui-plugin", + "@kbn/shared-ux-utility", + "@kbn/i18n-react", "@kbn/code-editor", "@kbn/monaco", + "@kbn/data-views-plugin", + "@kbn/lens-embeddable-utils", + "@kbn/lens-plugin", + "@kbn/expressions-plugin", + "@kbn/ui-actions-plugin", + "@kbn/esql-utils", + "@kbn/visualization-utils", + "@kbn/ai-assistant-management-plugin", "@kbn/utility-types-jest", + "@kbn/kibana-react-plugin", + "@kbn/licensing-plugin", + "@kbn/logging", + "@kbn/deeplinks-observability", + "@kbn/share-plugin", + "@kbn/observability-shared-plugin", "@kbn/ml-plugin", + "@kbn/data-plugin", "@kbn/react-kibana-context-theme", "@kbn/shared-ux-link-redirect-app", - "@kbn/shared-ux-utility", - "@kbn/data-plugin", + "@kbn/dev-cli-runner", + "@kbn/tooling-log", + "@kbn/babel-register", + "@kbn/expect", + "@kbn/apm-synthtrace-client", + "@kbn/alerting-plugin", + "@kbn/apm-synthtrace", + "@kbn/apm-utils", + "@kbn/config-schema", + "@kbn/es-query", + "@kbn/rule-registry-plugin", "@kbn/esql-validation-autocomplete", "@kbn/esql-ast", - "@kbn/ai-assistant-management-plugin", - "@kbn/deeplinks-observability", - "@kbn/management-settings-ids", - "@kbn/apm-utils", - "@kbn/alerting-plugin", + "@kbn/field-types", "@kbn/stack-connectors-plugin", "@kbn/features-plugin", "@kbn/serverless", "@kbn/task-manager-plugin", - "@kbn/cloud-plugin" + "@kbn/cloud-plugin", ], "exclude": ["target/**/*"] } From 06f3c30c9d1f58d9647ff73e1b2ff6ce582ba198 Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Wed, 1 May 2024 09:55:54 -0400 Subject: [PATCH 098/104] [Security Solution][Endpoint] Add validation to ensure a SentinelOne agent ID exists when enabling the `Respond` Take Action option (#182158) ## Summary - For alerts created against SentinelOne data: Fixes the display of "Respond" in the alert details panel "Take Action" menu so that it is disabled if the event data does not have the property that identifies the SentinelOne agent - A tooltip is displayed indicating why Responder is not available when it is disabled for this condition (see screen capture below) --- .../endpoint_responder/translations.ts | 11 +++++++ .../use_responder_action_data.test.ts | 30 ++++++++++++++++++- .../use_responder_action_data.ts | 24 ++++++++++++--- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/translations.ts b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/translations.ts index 3df858b9673f1..2badb70572c1d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/translations.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { SENTINEL_ONE_AGENT_ID_FIELD } from '../../../common/utils/sentinelone_alert_check'; export const NOT_FROM_ENDPOINT_HOST_TOOLTIP = i18n.translate( 'xpack.securitySolution.endpoint.detections.takeAction.responseActionConsole.notSupportedTooltip', @@ -25,3 +26,13 @@ export const METADATA_API_ERROR_TOOLTIP = i18n.translate( 'xpack.securitySolution.endpoint.detections.takeAction.responseActionConsole.generalMetadataErrorTooltip', { defaultMessage: 'Failed to retrieve Endpoint metadata' } ); + +export const SENTINEL_ONE_AGENT_ID_PROPERTY_MISSING = i18n.translate( + 'xpack.securitySolution.endpoint.detections.takeAction.responseActionConsole.missingSentinelOneAgentId', + { + defaultMessage: 'Event data missing SentinelOne agent identifier ({field})', + values: { + field: SENTINEL_ONE_AGENT_ID_FIELD, + }, + } +); diff --git a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.test.ts b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.test.ts index 5613cf551b464..e6b3b1886deec 100644 --- a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.test.ts +++ b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.test.ts @@ -10,6 +10,7 @@ import { useResponderActionData } from './use_responder_action_data'; import { renderHook } from '@testing-library/react-hooks'; import { useGetEndpointDetails } from '../../../management/hooks'; import { HostStatus } from '../../../../common/endpoint/types'; +import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; jest.mock('../../../common/hooks/use_experimental_features'); jest.mock('../../../management/hooks', () => ({ @@ -112,9 +113,33 @@ describe('#useResponderActionData', () => { }); describe('when agentType is `sentinel_one`', () => { + const createEventDataMock = (): TimelineEventsDetailsItem[] => { + return [ + { + category: 'observer', + field: 'observer.serial_number', + values: ['c06d63d9-9fa2-046d-e91e-dc94cf6695d8'], + originalValue: ['c06d63d9-9fa2-046d-e91e-dc94cf6695d8'], + isObjectArray: false, + }, + ]; + }; + it('should return `responder` menu item as `disabled` if agentType is `sentinel_one` and feature flag is disabled', () => { useIsExperimentalFeatureEnabledMock.mockReturnValue(false); + const { result } = renderHook(() => + useResponderActionData({ + endpointId: 'sentinel-one-id', + agentType: 'sentinel_one', + eventData: createEventDataMock(), + }) + ); + expect(result.current.isDisabled).toEqual(true); + }); + + it('should return responder menu item as disabled with tooltip if agent id property is missing from event data', () => { + useIsExperimentalFeatureEnabledMock.mockReturnValue(true); const { result } = renderHook(() => useResponderActionData({ endpointId: 'sentinel-one-id', @@ -123,6 +148,9 @@ describe('#useResponderActionData', () => { }) ); expect(result.current.isDisabled).toEqual(true); + expect(result.current.tooltip).toEqual( + 'Event data missing SentinelOne agent identifier (observer.serial_number)' + ); }); it('should return `responder` menu item as `enabled `if agentType is `sentinel_one` and feature flag is enabled', () => { @@ -131,7 +159,7 @@ describe('#useResponderActionData', () => { useResponderActionData({ endpointId: 'sentinel-one-id', agentType: 'sentinel_one', - eventData: [], + eventData: createEventDataMock(), }) ); expect(result.current.isDisabled).toEqual(false); diff --git a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts index 5e17f3178d59c..bf31ad493bbbc 100644 --- a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts +++ b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts @@ -21,6 +21,7 @@ import { LOADING_ENDPOINT_DATA_TOOLTIP, METADATA_API_ERROR_TOOLTIP, NOT_FROM_ENDPOINT_HOST_TOOLTIP, + SENTINEL_ONE_AGENT_ID_PROPERTY_MISSING, } from './translations'; import { getFieldValue } from '../host_isolation/helpers'; @@ -78,7 +79,6 @@ export const useResponderActionData = ({ tooltip: ReactNode; } => { const isEndpointHost = agentType === 'endpoint'; - const isSentinelOneHost = agentType === 'sentinel_one'; const showResponseActionsConsole = useWithShowResponder(); const isSentinelOneV1Enabled = useIsExperimentalFeatureEnabled( @@ -93,7 +93,22 @@ export const useResponderActionData = ({ const [isDisabled, tooltip]: [disabled: boolean, tooltip: ReactNode] = useMemo(() => { // v8.13 disabled for third-party agent alerts if the feature flag is not enabled if (!isEndpointHost) { - return [isSentinelOneHost ? !isSentinelOneV1Enabled : true, undefined]; + switch (agentType) { + case 'sentinel_one': + // Disable it if feature flag is disabled + if (!isSentinelOneV1Enabled) { + return [true, undefined]; + } + // Event must have the property that identifies the agent id + if (!getSentinelOneAgentId(eventData ?? null)) { + return [true, SENTINEL_ONE_AGENT_ID_PROPERTY_MISSING]; + } + + return [false, undefined]; + + default: + return [true, undefined]; + } } // Still loading host info @@ -125,11 +140,12 @@ export const useResponderActionData = ({ return [false, undefined]; }, [ isEndpointHost, - isSentinelOneHost, - isSentinelOneV1Enabled, isFetching, error, hostInfo?.host_status, + agentType, + isSentinelOneV1Enabled, + eventData, ]); const handleResponseActionsClick = useCallback(() => { From 0842c608452d4b7f9a746f9a51395116e325272a Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 1 May 2024 15:11:25 +0100 Subject: [PATCH 099/104] [ML] Fix retention of categorization example limits (#182103) When updating a job's model memory limits via the UI, if `categorization_examples_limit` has been set in `analysis_limits`, the configured value is replaced by the default value of `4`. This appears to be a [bug](https://github.com/elastic/elasticsearch/issues/108068) in elasticsearch and so this PR is a workaround to ensure the original `categorization_examples_limit` is sent as part of the update to ensure it isn't reset to the default. Also fixes an issue in the advanced job wizard where setting `categorization_examples_limit` in the JSON is not retained when saving the JSON. --- .../components/edit_job_flyout/edit_utils.js | 8 ++++++++ .../new_job/common/job_creator/job_creator.ts | 16 ++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index d587f83a50b5e..8870f04f498d0 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -104,6 +104,14 @@ function extractMML(job, newJobData) { if (mml !== job.analysis_limits.model_memory_limit) { mmlData.analysis_limits = { model_memory_limit: mml, + // work around for issue in es where categorization_examples_limit will be reset to the default value + // if it is not included in the update request + // https://github.com/elastic/elasticsearch/issues/108068 + ...(job.analysis_limits.categorization_examples_limit !== undefined + ? { + categorization_examples_limit: job.analysis_limits.categorization_examples_limit, + } + : {}), }; } } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts index 75eed3900950c..c7eda482aafad 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts @@ -21,6 +21,7 @@ import { } from '@kbn/ml-anomaly-utils'; import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import type { IndexPatternTitle } from '../../../../../../common/types/kibana'; import { getQueryFromSavedSearchObject } from '../../../../util/index_utils'; import type { @@ -327,11 +328,18 @@ export class JobCreator { public set modelMemoryLimit(mml: string | null) { if (mml !== null) { - this._job_config.analysis_limits = { - model_memory_limit: mml, - }; + if (this._job_config.analysis_limits === undefined) { + this._job_config.analysis_limits = {}; + } + this._job_config.analysis_limits.model_memory_limit = mml; } else { - delete this._job_config.analysis_limits; + if (this._job_config.analysis_limits !== undefined) { + delete this._job_config.analysis_limits.model_memory_limit; + + if (isPopulatedObject(this._job_config.analysis_limits) === false) { + delete this._job_config.analysis_limits; + } + } } } From f3d18faab29dcf0f75813561ff69e4c4bc976860 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 1 May 2024 16:13:53 +0200 Subject: [PATCH 100/104] [ES|QL] Rename the setting to a more generic one and move to the general section (#182074) ## Summary Renames the setting from discover:enableESQL to enableESQL and moves it to the General Section image We checked the telemetry and a very small percentage of users have switched off this setting. It was also on tech preview so we decided in favor of this change as more and more applications are using this setting to hide ESQL from their applications. image ### Release note We renamed the advanced setting which hides the ES|QL from the UI from `discover:enableESQL` to `enableESQL`. You have to switch it off again if you want to disable ES|QL features from your kibana applications. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- config/serverless.yml | 2 +- docs/discover/try-esql.asciidoc | 2 +- docs/management/advanced-options.asciidoc | 6 ++-- packages/kbn-discover-utils/index.ts | 1 - packages/kbn-discover-utils/src/constants.ts | 1 - packages/kbn-esql-utils/constants.ts | 1 + packages/kbn-esql-utils/index.ts | 2 +- .../settings/setting_ids/index.ts | 2 +- .../components/top_nav/discover_topnav.tsx | 2 +- src/plugins/discover/public/plugin.tsx | 3 +- src/plugins/discover/server/ui_settings.ts | 22 ------------ .../server/collectors/management/schema.ts | 2 +- .../server/collectors/management/types.ts | 2 +- src/plugins/telemetry/schema/oss_plugins.json | 2 +- src/plugins/text_based_languages/kibana.jsonc | 2 +- .../text_based_languages/server/index.ts | 12 +++++++ .../text_based_languages/server/plugin.ts | 23 ++++++++++++ .../server/ui_settings.ts | 36 +++++++++++++++++++ .../text_based_languages/tsconfig.json | 5 ++- .../apps/discover/group3/_request_counts.ts | 2 +- .../apps/discover/group4/_esql_view.ts | 2 +- .../index_data_visualizer.tsx | 2 +- x-pack/plugins/data_visualizer/tsconfig.json | 1 - .../lens/public/embeddable/embeddable.tsx | 3 +- .../open_lens_config/create_action.test.tsx | 2 +- .../open_lens_config/create_action_helpers.ts | 4 +-- .../in_app_embeddable_edit_action.test.tsx | 2 +- .../in_app_embeddable_edit_action_helpers.tsx | 3 +- .../datavisualizer_selector.tsx | 2 +- x-pack/plugins/ml/public/plugin.ts | 2 +- x-pack/plugins/ml/tsconfig.json | 2 +- .../logs_explorer/public/hooks/use_esql.tsx | 4 +-- .../logs_explorer/tsconfig.json | 1 + .../functions/query/esql_docs/esql-kibana.txt | 2 +- .../expression/query_form_type_chooser.tsx | 2 +- .../translations/translations/fr-FR.json | 4 +-- .../translations/translations/ja-JP.json | 4 +-- .../translations/translations/zh-CN.json | 4 +-- .../apps/discover/visualize_field.ts | 2 +- .../tests/apps/discover/async_search.ts | 2 +- 40 files changed, 117 insertions(+), 63 deletions(-) create mode 100644 src/plugins/text_based_languages/server/index.ts create mode 100644 src/plugins/text_based_languages/server/plugin.ts create mode 100644 src/plugins/text_based_languages/server/ui_settings.ts diff --git a/config/serverless.yml b/config/serverless.yml index 6fbe9496f705b..726d0540e1dfe 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -138,7 +138,7 @@ xpack.actions.queued.max: 10000 # Disables ESQL in advanced settings (hides it from the UI) uiSettings: overrides: - discover:enableESQL: true + enableESQL: true # Task Manager xpack.task_manager.allow_reading_invalid_state: false diff --git a/docs/discover/try-esql.asciidoc b/docs/discover/try-esql.asciidoc index 6c827240c1832..c95733fd42e6b 100644 --- a/docs/discover/try-esql.asciidoc +++ b/docs/discover/try-esql.asciidoc @@ -11,7 +11,7 @@ In this tutorial we'll use the {kib} sample web logs in Discover and Lens to exp [[prerequisite]] === Prerequisite -To be able to select **Try {esql}** from the Data views menu the `discover:enableESQL` setting must be enabled from **Stack Management > Advanced Settings**. It is enabled by default. +To be able to select **Try {esql}** from the Data views menu the `enableESQL` setting must be enabled from **Stack Management > Advanced Settings**. It is enabled by default. [float] [[tutorial-try-esql]] diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 9e400f01c88dd..3501b440d13ba 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -209,6 +209,9 @@ The default selection in the time filter. The maximum height that a cell occupies in a table. Set to 0 to disable truncation. +[[enableESQL]]`enableESQL`:: +This setting enables ES|QL in Kibana. + [float] [[presentation-labs]] ==== Presentation Labs @@ -290,9 +293,6 @@ in the current data view is used. The columns that appear by default on the *Discover* page. The default is `_source`. -[[discover:enableESQL]]`discover:enableESQL`:: -experimental[] Allows ES|QL queries for search. - [[discover-max-doc-fields-displayed]]`discover:maxDocFieldsDisplayed`:: Specifies the maximum number of fields to show in the document column of the *Discover* table. diff --git a/packages/kbn-discover-utils/index.ts b/packages/kbn-discover-utils/index.ts index 0434a05a9ce92..7a7fedfb5f1e3 100644 --- a/packages/kbn-discover-utils/index.ts +++ b/packages/kbn-discover-utils/index.ts @@ -13,7 +13,6 @@ export { DEFAULT_COLUMNS_SETTING, DOC_HIDE_TIME_COLUMN_SETTING, DOC_TABLE_LEGACY, - ENABLE_ESQL, FIELDS_LIMIT_SETTING, HIDE_ANNOUNCEMENTS, MAX_DOC_FIELDS_DISPLAYED, diff --git a/packages/kbn-discover-utils/src/constants.ts b/packages/kbn-discover-utils/src/constants.ts index 7582b610c6638..acd34290d29de 100644 --- a/packages/kbn-discover-utils/src/constants.ts +++ b/packages/kbn-discover-utils/src/constants.ts @@ -12,7 +12,6 @@ export const CONTEXT_TIE_BREAKER_FIELDS_SETTING = 'context:tieBreakerFields'; export const DEFAULT_COLUMNS_SETTING = 'defaultColumns'; export const DOC_HIDE_TIME_COLUMN_SETTING = 'doc_table:hideTimeColumn'; export const DOC_TABLE_LEGACY = 'doc_table:legacy'; -export const ENABLE_ESQL = 'discover:enableESQL'; export const FIELDS_LIMIT_SETTING = 'fields:popularLimit'; export const HIDE_ANNOUNCEMENTS = 'hideAnnouncements'; export const MAX_DOC_FIELDS_DISPLAYED = 'discover:maxDocFieldsDisplayed'; diff --git a/packages/kbn-esql-utils/constants.ts b/packages/kbn-esql-utils/constants.ts index 51dcbab83654b..a50f03ebea1e2 100644 --- a/packages/kbn-esql-utils/constants.ts +++ b/packages/kbn-esql-utils/constants.ts @@ -9,3 +9,4 @@ // we are expecting to retrieve this from an API instead // https://github.com/elastic/elasticsearch/issues/107069 export const ESQL_LATEST_VERSION = '2024.04.01'; +export const ENABLE_ESQL = 'enableESQL'; diff --git a/packages/kbn-esql-utils/index.ts b/packages/kbn-esql-utils/index.ts index 0d04f40b85612..f8e93981d9c24 100644 --- a/packages/kbn-esql-utils/index.ts +++ b/packages/kbn-esql-utils/index.ts @@ -19,4 +19,4 @@ export { TextBasedLanguages, } from './src'; -export { ESQL_LATEST_VERSION } from './constants'; +export { ESQL_LATEST_VERSION, ENABLE_ESQL } from './constants'; diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 771d60fb573aa..f4a30dac6cb12 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -73,7 +73,7 @@ export const CONTEXT_DEFAULT_SIZE_ID = 'context:defaultSize'; export const CONTEXT_STEP_ID = 'context:step'; export const CONTEXT_TIE_BREAKER_FIELDS_ID = 'context:tieBreakerFields'; export const DEFAULT_COLUMNS_ID = 'defaultColumns'; -export const DISCOVER_ENABLE_ESQL_ID = 'discover:enableESQL'; +export const ENABLE_ESQL_ID = 'enableESQL'; export const DISCOVER_MAX_DOC_FIELDS_DISPLAYED_ID = 'discover:maxDocFieldsDisplayed'; export const DISCOVER_MODIFY_COLUMNS_ON_SWITCH_ID = 'discover:modifyColumnsOnSwitch'; export const DISCOVER_ROW_HEIGHT_OPTION_ID = 'discover:rowHeightOption'; diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx index 0af9e4ab303a4..9353df2c63a2d 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import type { AggregateQuery, Query, TimeRange } from '@kbn/es-query'; import { type DataView, DataViewType } from '@kbn/data-views-plugin/public'; import { DataViewPickerProps } from '@kbn/unified-search-plugin/public'; -import { ENABLE_ESQL } from '@kbn/discover-utils'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { TextBasedLanguages } from '@kbn/esql-utils'; import { useSavedSearch, diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 902cc0a38e717..3563697138cc4 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -29,6 +29,7 @@ import { HomePublicPluginSetup } from '@kbn/home-plugin/public'; import { Start as InspectorPublicPluginStart } from '@kbn/inspector-plugin/public'; import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public'; import { DataViewsServicePublic } from '@kbn/data-views-plugin/public'; @@ -44,7 +45,7 @@ import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/ import type { UnifiedDocViewerStart } from '@kbn/unified-doc-viewer-plugin/public'; import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; -import { TRUNCATE_MAX_HEIGHT, ENABLE_ESQL } from '@kbn/discover-utils'; +import { TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils'; import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public'; import type { ObservabilityAIAssistantPublicSetup, diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index f09d96f150a9b..fab0d56c0d828 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -30,7 +30,6 @@ import { TRUNCATE_MAX_HEIGHT, SHOW_FIELD_STATISTICS, ROW_HEIGHT_OPTION, - ENABLE_ESQL, } from '@kbn/discover-utils'; import { DEFAULT_ROWS_PER_PAGE, ROWS_PER_PAGE_OPTIONS } from '../common/constants'; @@ -310,25 +309,4 @@ export const getUiSettings: ( schema: schema.number({ min: 0 }), requiresPageReload: true, }, - [ENABLE_ESQL]: { - name: i18n.translate('discover.advancedSettings.enableESQLTitle', { - defaultMessage: 'Enable ES|QL', - }), - value: true, - description: i18n.translate('discover.advancedSettings.enableESQLDescription', { - defaultMessage: - 'This setting enables ES|QL in Kibana. By switching it off you will hide the ES|QL user interface from various applications. However, users will be able to access existing ES|QL saved searches, visualizations, etc. If you have feedback on this experience please reach out to us on {link}', - values: { - link: - `` + - i18n.translate('discover.advancedSettings.enableESQL.discussLinkText', { - defaultMessage: 'https://ela.st/esql-feedback', - }) + - '', - }, - }), - requiresPageReload: true, - category: ['discover'], - schema: schema.boolean(), - }, }); diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 0ed695f0b1999..1cf68fdf92f36 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -539,7 +539,7 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'discover:enableESQL': { + enableESQL: { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 86c25366d4ceb..8464207aaa1d6 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -34,7 +34,7 @@ export interface UsageStats { 'discover:searchFieldsFromSource': boolean; 'discover:showFieldStatistics': boolean; 'discover:showMultiFields': boolean; - 'discover:enableESQL': boolean; + enableESQL: boolean; 'discover:maxDocFieldsDisplayed': number; 'securitySolution:rulesTableRefresh': string; 'observability:enableInspectEsQueries': boolean; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 8773c3a99f9d2..f5eb21f859bca 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10254,7 +10254,7 @@ "description": "Non-default value of setting." } }, - "discover:enableESQL": { + "enableESQL": { "type": "boolean", "_meta": { "description": "Non-default value of setting." diff --git a/src/plugins/text_based_languages/kibana.jsonc b/src/plugins/text_based_languages/kibana.jsonc index 545c1878cc4e4..7e9aba22067e8 100644 --- a/src/plugins/text_based_languages/kibana.jsonc +++ b/src/plugins/text_based_languages/kibana.jsonc @@ -4,7 +4,7 @@ "owner": "@elastic/kibana-esql", "plugin": { "id": "textBasedLanguages", - "server": false, + "server": true, "browser": true, "optionalPlugins": [ "indexManagement" diff --git a/src/plugins/text_based_languages/server/index.ts b/src/plugins/text_based_languages/server/index.ts new file mode 100644 index 0000000000000..bca404b161bf8 --- /dev/null +++ b/src/plugins/text_based_languages/server/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const plugin = async () => { + const { TextBasedLanguagesServerPlugin } = await import('./plugin'); + return new TextBasedLanguagesServerPlugin(); +}; diff --git a/src/plugins/text_based_languages/server/plugin.ts b/src/plugins/text_based_languages/server/plugin.ts new file mode 100644 index 0000000000000..95a341a467cc5 --- /dev/null +++ b/src/plugins/text_based_languages/server/plugin.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/server'; +import { getUiSettings } from './ui_settings'; + +export class TextBasedLanguagesServerPlugin implements Plugin { + public setup(core: CoreSetup) { + core.uiSettings.register(getUiSettings()); + return {}; + } + + public start(core: CoreStart) { + return {}; + } + + public stop() {} +} diff --git a/src/plugins/text_based_languages/server/ui_settings.ts b/src/plugins/text_based_languages/server/ui_settings.ts new file mode 100644 index 0000000000000..32717b0d2cb8c --- /dev/null +++ b/src/plugins/text_based_languages/server/ui_settings.ts @@ -0,0 +1,36 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { schema } from '@kbn/config-schema'; + +import type { UiSettingsParams } from '@kbn/core/server'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; + +export const getUiSettings: () => Record = () => ({ + [ENABLE_ESQL]: { + name: i18n.translate('textBasedLanguages.advancedSettings.enableESQLTitle', { + defaultMessage: 'Enable ES|QL', + }), + value: true, + description: i18n.translate('textBasedLanguages.advancedSettings.enableESQLDescription', { + defaultMessage: + 'This setting enables ES|QL in Kibana. By switching it off you will hide the ES|QL user interface from various applications. However, users will be able to access existing ES|QL saved searches, visualizations, etc. If you have feedback on this experience please reach out to us on {link}', + values: { + link: + `` + + i18n.translate('textBasedLanguages.advancedSettings.enableESQL.discussLinkText', { + defaultMessage: 'https://ela.st/esql-feedback', + }) + + '', + }, + }), + requiresPageReload: true, + schema: schema.boolean(), + }, +}); diff --git a/src/plugins/text_based_languages/tsconfig.json b/src/plugins/text_based_languages/tsconfig.json index 8d3fef08e23a9..2cb4eddcbf7a0 100644 --- a/src/plugins/text_based_languages/tsconfig.json +++ b/src/plugins/text_based_languages/tsconfig.json @@ -15,7 +15,10 @@ "@kbn/core", "@kbn/expressions-plugin", "@kbn/data-views-plugin", - "@kbn/index-management" + "@kbn/index-management", + "@kbn/i18n", + "@kbn/config-schema", + "@kbn/esql-utils" ], "exclude": [ "target/**/*", diff --git a/test/functional/apps/discover/group3/_request_counts.ts b/test/functional/apps/discover/group3/_request_counts.ts index 636f3343877fd..3503258cb6c0e 100644 --- a/test/functional/apps/discover/group3/_request_counts.ts +++ b/test/functional/apps/discover/group3/_request_counts.ts @@ -37,7 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*', 'bfetch:disable': true, - 'discover:enableESQL': true, + enableESQL: true, }); await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); }); diff --git a/test/functional/apps/discover/group4/_esql_view.ts b/test/functional/apps/discover/group4/_esql_view.ts index 31f323500b119..57c924e44693a 100644 --- a/test/functional/apps/discover/group4/_esql_view.ts +++ b/test/functional/apps/discover/group4/_esql_view.ts @@ -35,7 +35,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const defaultSettings = { defaultIndex: 'logstash-*', - 'discover:enableESQL': true, + enableESQL: true, }; describe('discover esql view', async function () { 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 7482e686db33e..d5f8f17b9ee17 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 @@ -32,7 +32,7 @@ import { UrlStateProvider, } from '@kbn/ml-url-state'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { ENABLE_ESQL } from '@kbn/discover-utils'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { EuiCallOut } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { getCoreStart, getPluginsStart } from '../../kibana_services'; diff --git a/x-pack/plugins/data_visualizer/tsconfig.json b/x-pack/plugins/data_visualizer/tsconfig.json index 428311f87b305..61a7a80484eb9 100644 --- a/x-pack/plugins/data_visualizer/tsconfig.json +++ b/x-pack/plugins/data_visualizer/tsconfig.json @@ -78,7 +78,6 @@ "@kbn/visualization-utils", "@kbn/ml-time-buckets", "@kbn/aiops-log-rate-analysis", - "@kbn/discover-utils", "@kbn/react-kibana-context-render", "@kbn/react-kibana-context-theme" ], diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index d4db046665fc7..3206947c2a9b7 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -11,6 +11,7 @@ import type { Observable } from 'rxjs'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; import { render, unmountComponentAtNode } from 'react-dom'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { DataViewBase, EsQueryConfig, @@ -1556,7 +1557,7 @@ export class Embeddable public getIsEditable() { // for ES|QL, editing is allowed only if the advanced setting is on - if (Boolean(this.isTextBasedLanguage()) && !this.deps.uiSettings.get('discover:enableESQL')) { + if (Boolean(this.isTextBasedLanguage()) && !this.deps.uiSettings.get(ENABLE_ESQL)) { return false; } return ( diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx index 27372f10ce973..97b59a93829e3 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx @@ -32,7 +32,7 @@ describe('create Lens panel action', () => { uiSettings: { ...core.uiSettings, get: (setting: string) => { - return setting === 'discover:enableESQL'; + return setting === 'enableESQL'; }, }, } as CoreStart; diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts index 3e77f8979a872..b99583ddf3103 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts @@ -9,7 +9,7 @@ import type { CoreStart } from '@kbn/core/public'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { PresentationContainer } from '@kbn/presentation-containers'; -import { getESQLAdHocDataview, getIndexForESQLQuery } from '@kbn/esql-utils'; +import { getESQLAdHocDataview, getIndexForESQLQuery, ENABLE_ESQL } from '@kbn/esql-utils'; import type { Datasource, Visualization } from '../../types'; import type { LensPluginStartDependencies } from '../../plugin'; import { fetchDataFromAggregateQuery } from '../../datasources/text_based/fetch_data_from_aggregate_query'; @@ -28,7 +28,7 @@ export const [getDatasourceMap, setDatasourceMap] = createGetterSetter< >('DatasourceMap', false); export function isCreateActionCompatible(core: CoreStart) { - return core.uiSettings.get('discover:enableESQL'); + return core.uiSettings.get(ENABLE_ESQL); } export async function executeCreateAction({ diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action.test.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action.test.tsx index a6c7a8bcf6bc0..7525f491e697a 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action.test.tsx +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action.test.tsx @@ -51,7 +51,7 @@ describe('inapp editing of Lens embeddable', () => { uiSettings: { ...core.uiSettings, get: (setting: string) => { - return setting === 'discover:enableESQL'; + return setting === 'enableESQL'; }, }, } as CoreStart; diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action_helpers.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action_helpers.tsx index 168dbebe3ebd2..0a3dc8feebe0b 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action_helpers.tsx +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/in_app_embeddable_edit/in_app_embeddable_edit_action_helpers.tsx @@ -8,6 +8,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import type { CoreStart } from '@kbn/core/public'; import { isOfAggregateQueryType } from '@kbn/es-query'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import type { LensPluginStartDependencies } from '../../../plugin'; @@ -21,7 +22,7 @@ export function isEmbeddableEditActionCompatible( ) { // for ES|QL is compatible only when advanced setting is enabled const query = attributes.state.query; - return isOfAggregateQueryType(query) ? core.uiSettings.get('discover:enableESQL') : true; + return isOfAggregateQueryType(query) ? core.uiSettings.get(ENABLE_ESQL) : true; } export async function executeEditEmbeddableAction({ diff --git a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx index 1b5f3acdaedd2..41b2ac3a47d37 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx @@ -23,7 +23,7 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { useTimefilter } from '@kbn/ml-date-picker'; -import { ENABLE_ESQL } from '@kbn/discover-utils'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { isFullLicense } from '../license'; import { useMlKibana, useNavigateToPath } from '../contexts/kibana'; import { HelpMenu } from '../components/help_menu'; diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index e3bf7e3520649..d762bb9557268 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -50,7 +50,7 @@ import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/publ import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; import type { FieldFormatsRegistry } from '@kbn/field-formats-plugin/common'; -import { ENABLE_ESQL } from '@kbn/discover-utils'; +import { ENABLE_ESQL } from '@kbn/esql-utils'; import type { MlSharedServices } from './application/services/get_shared_ml_services'; import { getMlSharedServices } from './application/services/get_shared_ml_services'; import { registerManagementSection } from './application/management'; diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index dba33a6043bc8..4b3ae3a3f0beb 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -124,7 +124,7 @@ "@kbn/presentation-containers", "@kbn/presentation-panel-plugin", "@kbn/shared-ux-utility", - "@kbn/discover-utils", "@kbn/react-kibana-context-render", + "@kbn/esql-utils", ], } diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/hooks/use_esql.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/hooks/use_esql.tsx index b34cae81f303a..e26474b6165e6 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/hooks/use_esql.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/hooks/use_esql.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { ENABLE_ESQL } from '@kbn/esql-utils'; import { DataSourceSelection, isDatasetSelection } from '../../common/data_source_selection'; import { useKibanaContextForPlugin } from '../utils/use_kibana'; @@ -27,7 +27,7 @@ export const useEsql = ({ dataSourceSelection }: EsqlContextDeps): UseEsqlResult services: { uiSettings, discover }, } = useKibanaContextForPlugin(); - const isEsqlEnabled = uiSettings?.get('discover:enableESQL'); + const isEsqlEnabled = uiSettings?.get(ENABLE_ESQL); const esqlPattern = isDatasetSelection(dataSourceSelection) ? dataSourceSelection.selection.dataset.name diff --git a/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json b/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json index 7c4224eadac19..35bd2b0a7ffb2 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json +++ b/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json @@ -46,6 +46,7 @@ "@kbn/unified-field-list", "@kbn/unified-search-plugin", "@kbn/xstate-utils", + "@kbn/esql-utils", ], "exclude": [ "target/**/*" diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-kibana.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-kibana.txt index 798a9befd7647..5fcce8c997ee7 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-kibana.txt +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-kibana.txt @@ -10,7 +10,7 @@ Get started with ES|QLedit To get started with ES|QL in Discover, open the main menu and select Discover. Next, from the Data views menu, select Try ES|QL. The ability to select ES|QL from the Data views menu can be enabled and -disabled using the `discover:enableESQL` setting from +disabled using the `enableESQL` setting from Advanced Settings. The query baredit After switching to ES|QL mode, the query bar shows a sample query. For example: diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/query_form_type_chooser.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/query_form_type_chooser.tsx index f551d078314b6..005adb7be25ef 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/query_form_type_chooser.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/query_form_type_chooser.tsx @@ -50,7 +50,7 @@ export const QueryFormTypeChooser: React.FC = ({ onFormTypeSelect, }) => { const { uiSettings } = useTriggerUiActionServices(); - const isEsqlEnabled = uiSettings?.get('discover:enableESQL'); + const isEsqlEnabled = uiSettings?.get('enableESQL'); const formTypeItems = useMemo(() => { const items: Array<{ formType: SearchType; label: string; description: string }> = [ diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index d65c505c95ea7..7e7d4218db8fe 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -2301,8 +2301,8 @@ "discover.advancedSettings.docTableHideTimeColumnText": "Permet de masquer la colonne ''Time'' dans Discover et dans toutes les recherches enregistrées des tableaux de bord.", "discover.advancedSettings.docTableHideTimeColumnTitle": "Masquer la colonne ''Time''", "discover.advancedSettings.documentExplorerLinkText": "Explorateur de documents", - "discover.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", - "discover.advancedSettings.enableESQLTitle": "Activer ES|QL", + "textBasedLanguages.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", + "textBasedLanguages.advancedSettings.enableESQLTitle": "Activer ES|QL", "discover.advancedSettings.fieldsPopularLimitText": "Les N champs les plus populaires à afficher", "discover.advancedSettings.fieldsPopularLimitTitle": "Limite de champs populaires", "discover.advancedSettings.maxDocFieldsDisplayedText": "Le nombre maximal de champs renvoyés dans le résumé du document", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a90eb95137a9c..60e15dd80a172 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2299,8 +2299,8 @@ "discover.advancedSettings.docTableHideTimeColumnText": "Discover と、ダッシュボードのすべての保存された検索で、「時刻」列を非表示にします。", "discover.advancedSettings.docTableHideTimeColumnTitle": "「時刻」列を非表示", "discover.advancedSettings.documentExplorerLinkText": "ドキュメントエクスプローラー", - "discover.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", - "discover.advancedSettings.enableESQLTitle": "ES|QLを有効化", + "textBasedLanguages.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", + "textBasedLanguages.advancedSettings.enableESQLTitle": "ES|QLを有効化", "discover.advancedSettings.fieldsPopularLimitText": "最も頻繁に使用されるフィールドのトップNを表示します", "discover.advancedSettings.fieldsPopularLimitTitle": "頻繁に使用されるフィールドの制限", "discover.advancedSettings.maxDocFieldsDisplayedText": "ドキュメント概要でレンダリングされるフィールドの最大数", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 45b79ec3364c3..430a3b8d46916 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2303,8 +2303,8 @@ "discover.advancedSettings.docTableHideTimeColumnText": "在 Discover 中和仪表板上的所有已保存搜索中隐藏“时间”列。", "discover.advancedSettings.docTableHideTimeColumnTitle": "隐藏“时间”列", "discover.advancedSettings.documentExplorerLinkText": "Document Explorer", - "discover.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", - "discover.advancedSettings.enableESQLTitle": "启用 ES|QL", + "textBasedLanguages.advancedSettings.enableESQL.discussLinkText": "discuss.elastic.co/c/elastic-stack/kibana", + "textBasedLanguages.advancedSettings.enableESQLTitle": "启用 ES|QL", "discover.advancedSettings.fieldsPopularLimitText": "要显示的排名前 N 最常见字段", "discover.advancedSettings.fieldsPopularLimitTitle": "常见字段限制", "discover.advancedSettings.maxDocFieldsDisplayedText": "在文档摘要中渲染的最大字段数目", diff --git a/x-pack/test/functional/apps/discover/visualize_field.ts b/x-pack/test/functional/apps/discover/visualize_field.ts index e2cb7962db7ae..b1eadf89a5297 100644 --- a/x-pack/test/functional/apps/discover/visualize_field.ts +++ b/x-pack/test/functional/apps/discover/visualize_field.ts @@ -31,7 +31,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const monacoEditor = getService('monacoEditor'); const defaultSettings = { - 'discover:enableESQL': true, + enableESQL: true, }; async function setDiscoverTimeRange() { diff --git a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts index ae1004db12cf3..7fdea1ff3d648 100644 --- a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts +++ b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts @@ -35,7 +35,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'x-pack/test/functional/fixtures/kbn_archiver/discover/default' ); await kibanaServer.uiSettings.replace({ - 'discover:enableESQL': true, + enableESQL: true, }); await PageObjects.common.navigateToApp('discover'); await PageObjects.timePicker.setDefaultAbsoluteRange(); From 0288bb466403452dad0fe0958da9a2249a473072 Mon Sep 17 00:00:00 2001 From: Samiul Monir <150824886+Samiul-TheSoccerFan@users.noreply.github.com> Date: Wed, 1 May 2024 10:22:41 -0400 Subject: [PATCH 101/104] [Playground] Propagate Error message into FE (#182201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Fix error not being propagated into FE - Added tests ## UI ### Rate limit error message: ![Screenshot 2024-04-30 at 1 05 40 PM](https://github.com/elastic/kibana/assets/150824886/2734d27b-ef2b-469b-9344-a7c62cd502bc) ### BAD LLM ![Screenshot 2024-04-30 at 1 05 47 PM](https://github.com/elastic/kibana/assets/150824886/fb3025e5-5f5e-49e6-8277-7dba52cc76cd) ### Invalid API key ![Screenshot 2024-04-30 at 1 06 26 PM](https://github.com/elastic/kibana/assets/150824886/67c1bdf6-6785-48ed-870a-ae24e8ac7e9f) ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../__mocks__/router.mock.ts | 95 +++++++++++++++++++ .../search_playground/server/routes.test.ts | 86 ++++++++++++++++- .../search_playground/server/routes.ts | 4 +- .../plugins/search_playground/tsconfig.json | 3 +- 4 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/search_playground/__mocks__/router.mock.ts diff --git a/x-pack/plugins/search_playground/__mocks__/router.mock.ts b/x-pack/plugins/search_playground/__mocks__/router.mock.ts new file mode 100644 index 0000000000000..328f44997b757 --- /dev/null +++ b/x-pack/plugins/search_playground/__mocks__/router.mock.ts @@ -0,0 +1,95 @@ +/* + * 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 { + IRouter, + KibanaRequest, + RequestHandlerContext, + RouteValidatorConfig, +} from '@kbn/core/server'; +import { httpServiceMock, httpServerMock } from '@kbn/core/server/mocks'; + +/** + * Test helper that mocks Kibana's router and DRYs out various helper (callRoute, schema validation) + */ + +type MethodType = 'get' | 'post' | 'put' | 'patch' | 'delete'; +type PayloadType = 'params' | 'query' | 'body'; + +interface IMockRouter { + method: MethodType; + path: string; + context?: jest.Mocked; +} +interface IMockRouterRequest { + body?: object; + query?: object; + params?: object; +} +type MockRouterRequest = KibanaRequest | IMockRouterRequest; + +export class MockRouter { + public router!: jest.Mocked; + public method: MethodType; + public path: string; + public context: jest.Mocked; + public payload?: PayloadType; + public response = httpServerMock.createResponseFactory(); + + constructor({ method, path, context = {} as jest.Mocked }: IMockRouter) { + this.createRouter(); + this.method = method; + this.path = path; + this.context = context; + } + + public createRouter = () => { + this.router = httpServiceMock.createRouter(); + }; + + public callRoute = async (request: MockRouterRequest) => { + const route = this.findRouteRegistration(); + const [, handler] = route; + await handler(this.context, httpServerMock.createKibanaRequest(request as any), this.response); + }; + + /** + * Schema validation helpers + */ + + public validateRoute = (request: MockRouterRequest) => { + const route = this.findRouteRegistration(); + const [config] = route; + const validate = config.validate as RouteValidatorConfig<{}, {}, {}>; + const payloads = Object.keys(request) as PayloadType[]; + + payloads.forEach((payload: PayloadType) => { + const payloadValidation = validate[payload] as { validate(request: KibanaRequest): void }; + const payloadRequest = request[payload] as KibanaRequest; + + payloadValidation.validate(payloadRequest); + }); + }; + + public shouldValidate = (request: MockRouterRequest) => { + expect(() => this.validateRoute(request)).not.toThrow(); + }; + + public shouldThrow = (request: MockRouterRequest) => { + expect(() => this.validateRoute(request)).toThrow(); + }; + + private findRouteRegistration = () => { + const routerCalls = this.router[this.method].mock.calls as any[]; + if (!routerCalls.length) throw new Error('No routes registered.'); + + const route = routerCalls.find(([router]: any) => router.path === this.path); + if (!route) throw new Error('No matching registered routes found - check method/path keys'); + + return route; + }; +} diff --git a/x-pack/plugins/search_playground/server/routes.test.ts b/x-pack/plugins/search_playground/server/routes.test.ts index b149fde95c1e4..b845f99576e61 100644 --- a/x-pack/plugins/search_playground/server/routes.test.ts +++ b/x-pack/plugins/search_playground/server/routes.test.ts @@ -5,7 +5,19 @@ * 2.0. */ -import { createRetriever } from './routes'; +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import { RequestHandlerContext } from '@kbn/core/server'; +import { coreMock } from '@kbn/core/server/mocks'; +import { MockRouter } from '../__mocks__/router.mock'; +import { ConversationalChain } from './lib/conversational_chain'; +import { getChatParams } from './lib/get_chat_params'; +import { createRetriever, defineRoutes } from './routes'; + +jest.mock('./lib/get_chat_params', () => ({ + getChatParams: jest.fn(), +})); + +jest.mock('./lib/conversational_chain'); describe('createRetriever', () => { test('works when the question has quotes', () => { @@ -18,3 +30,75 @@ describe('createRetriever', () => { expect(result).toEqual({ query: { match: { text: 'How can I "do something" with quotes?' } } }); }); }); + +describe('Search Playground routes', () => { + let mockRouter: MockRouter; + const mockClient = { + asCurrentUser: {}, + }; + + const mockCore = { + elasticsearch: { client: mockClient }, + }; + const mockLogger = loggingSystemMock.createLogger().get(); + + describe('POST - Chat Messages', () => { + const mockData = { + connector_id: 'open-ai', + indices: 'my-index', + prompt: 'You are an assistant', + citations: true, + elasticsearch_query: {}, + summarization_model: 'GPT-4', + doc_size: 3, + source_fields: '{}', + }; + + const mockRequestBody = { + data: mockData, + }; + + beforeEach(() => { + jest.clearAllMocks(); + + const coreStart = coreMock.createStart(); + + const context = { + core: Promise.resolve(mockCore), + } as unknown as jest.Mocked; + + mockRouter = new MockRouter({ + context, + method: 'post', + path: '/internal/search_playground/chat', + }); + + defineRoutes({ + logger: mockLogger, + router: mockRouter.router, + getStartServices: jest.fn().mockResolvedValue([coreStart, {}, {}]), + }); + }); + + it('responds with error message if stream throws an error', async () => { + (getChatParams as jest.Mock).mockResolvedValue({ model: 'open-ai' }); + (ConversationalChain as jest.Mock).mockImplementation(() => { + return { + stream: jest + .fn() + .mockRejectedValue(new Error('Unexpected API error - Some Open AI error message')), + }; + }); + + await mockRouter.callRoute({ + body: mockRequestBody, + }); + + expect(mockRouter.response.badRequest).toHaveBeenCalledWith({ + body: { + message: 'Unexpected API error - Some Open AI error message', + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/search_playground/server/routes.ts b/x-pack/plugins/search_playground/server/routes.ts index 12ba2e89c66cd..e9f40d89d18fe 100644 --- a/x-pack/plugins/search_playground/server/routes.ts +++ b/x-pack/plugins/search_playground/server/routes.ts @@ -131,10 +131,10 @@ export function defineRoutes({ } catch (e) { logger.error('Failed to create the chat stream', e); - if (typeof e === 'string') { + if (typeof e === 'object') { return response.badRequest({ body: { - message: e, + message: e.message, }, }); } diff --git a/x-pack/plugins/search_playground/tsconfig.json b/x-pack/plugins/search_playground/tsconfig.json index 7a7ee54279017..4726066210d8f 100644 --- a/x-pack/plugins/search_playground/tsconfig.json +++ b/x-pack/plugins/search_playground/tsconfig.json @@ -35,7 +35,8 @@ "@kbn/elastic-assistant-common", "@kbn/logging", "@kbn/react-kibana-context-render", - "@kbn/doc-links" + "@kbn/doc-links", + "@kbn/core-logging-server-mocks" ], "exclude": [ "target/**/*", From 593d3911728cf68093925836ae2031746c7db6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Wed, 1 May 2024 17:41:31 +0200 Subject: [PATCH 102/104] Add `@typescript-eslint/no-floating-promises` (#181456) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Aleh Zasypkin Co-authored-by: Patrick Mueller --- examples/response_stream/server/plugin.ts | 2 +- .../server/routes/reducer_stream.ts | 69 +++--- .../server/routes/single_string_stream.ts | 4 +- examples/search_examples/server/plugin.ts | 2 +- .../http/cookie_session_storage.test.ts | 2 +- .../server/integration_tests/http/oas.test.ts | 2 +- .../integration_tests/http/router.test.ts | 6 +- .../migrations/group2/cleanup.test.ts | 6 +- .../migrations/group3/actions/actions.test.ts | 8 +- .../group3/actions/actions_test_suite.ts | 8 +- .../group3/default_search_fields.test.ts | 4 +- .../group3/split_failed_to_clone.test.ts | 4 +- .../group3/type_registrations.test.ts | 4 +- .../wait_for_migration_completion.test.ts | 2 +- .../migrations/kibana_migrator_test_kit.ts | 6 +- .../validation/validator.test.ts | 4 +- .../eslint/types.eslint.config.template.js | 10 + .../server/core/core.test.ts | 10 +- .../server/rpc/procedures/bulk_get.test.ts | 16 +- .../server/rpc/procedures/create.test.ts | 12 +- .../server/rpc/procedures/delete.test.ts | 12 +- .../server/rpc/procedures/get.test.ts | 12 +- .../server/rpc/procedures/msearch.test.ts | 8 +- .../server/rpc/procedures/search.test.ts | 12 +- .../server/rpc/procedures/update.test.ts | 12 +- .../server/rpc/rpc_service.test.ts | 20 +- .../query/route_handler_context.test.ts | 10 +- .../server/search/collectors/search/usage.ts | 4 +- .../data/server/search/search_service.ts | 2 +- .../search/session/session_service.test.ts | 58 ++--- .../expressions/load_index_pattern.test.ts | 2 +- .../server/rest_api_routes/internal/fields.ts | 2 +- .../rest_api_routes/internal/fields_for.ts | 2 +- .../public/create_data_view.test.ts | 4 +- .../public/default_data_view.test.ts | 8 +- .../public/delete_data_view.test.ts | 4 +- .../public/fields/update_fields.test.ts | 4 +- .../public/get_data_view.test.ts | 4 +- .../public/get_data_views.test.ts | 4 +- .../public/has_user_data_view.test.ts | 4 +- .../create_runtime_field.test.ts | 4 +- .../delete_runtime_field.test.ts | 4 +- .../runtime_fields/get_runtime_field.test.ts | 4 +- .../runtime_fields/put_runtime_field.test.ts | 4 +- .../update_runtime_field.test.ts | 4 +- .../public/update_data_view.test.ts | 4 +- .../server/locator/title_from_locator.test.ts | 2 +- .../server/routes/file_kind/upload.test.ts | 2 +- .../files/server/routes/file_kind/upload.ts | 2 +- .../cloud/cloud_provider_collector.ts | 2 +- .../cloud/detector/cloud_detector.mock.ts | 2 +- src/plugins/maps_ems/server/plugin.ts | 5 +- src/plugins/navigation/server/plugin.ts | 14 +- .../server/stream_factory.test.ts | 4 +- x-pack/plugins/actions/server/plugin.ts | 10 +- .../server/routes/connector/get/get.test.ts | 2 +- .../routes/connector/get_all/get_all.test.ts | 2 +- .../get_all_system/get_all_system.test.ts | 2 +- .../connector/list_types/list_types.test.ts | 2 +- .../list_types_system.test.ts | 2 +- .../actions/server/routes/create.test.ts | 2 +- .../actions/server/routes/delete.test.ts | 2 +- .../actions/server/routes/execute.test.ts | 2 +- .../routes/get_oauth_access_token.test.ts | 2 +- .../server/routes/legacy/create.test.ts | 2 +- .../server/routes/legacy/delete.test.ts | 2 +- .../server/routes/legacy/execute.test.ts | 2 +- .../actions/server/routes/legacy/get.test.ts | 2 +- .../server/routes/legacy/get_all.test.ts | 2 +- .../routes/legacy/list_action_types.test.ts | 2 +- .../server/routes/legacy/update.test.ts | 2 +- .../actions/server/routes/update.test.ts | 2 +- x-pack/plugins/actions/server/usage/task.ts | 4 +- x-pack/plugins/aiops/server/plugin.ts | 2 +- .../analysis_handlers/grouping_handler.ts | 2 +- .../analysis_handlers/histogram_handler.ts | 2 +- .../route_handler_factory.ts | 2 +- .../lib/install_with_timeout.ts | 10 +- .../methods/delete/delete_backfill.test.ts | 2 +- .../methods/delete/delete_backfill.ts | 2 +- .../rule/methods/create/create_rule.test.ts | 2 +- .../rule/methods/update/update_rule.test.ts | 2 +- .../bulk_mark_api_keys_for_invalidation.ts | 2 +- x-pack/plugins/alerting/server/plugin.ts | 16 +- .../apis/delete/delete_backfill_route.test.ts | 2 +- .../apis/find/find_backfill_route.test.ts | 2 +- .../apis/get/get_backfill_route.test.ts | 2 +- .../schedule/schedule_backfill_route.test.ts | 2 +- .../server/routes/delete_rule.test.ts | 2 +- .../routes/get_action_error_log.test.ts | 2 +- .../routes/get_rule_alert_summary.test.ts | 2 +- .../routes/get_rule_execution_kpi.test.ts | 2 +- .../routes/get_rule_execution_log.test.ts | 2 +- .../server/routes/legacy/create.test.ts | 2 +- .../server/routes/legacy/delete.test.ts | 2 +- .../server/routes/legacy/find.test.ts | 2 +- .../alerting/server/routes/legacy/get.test.ts | 2 +- .../routes/legacy/list_alert_types.test.ts | 2 +- .../server/routes/legacy/update.test.ts | 2 +- .../archive_maintenance_window_route.test.ts | 4 +- ...bulk_get_maintenance_windows_route.test.ts | 4 +- .../create_maintenance_window_route.test.ts | 4 +- .../delete_maintenance_window_route.test.ts | 4 +- .../find_maintenance_windows_route.test.ts | 4 +- .../finish_maintenance_window_route.test.ts | 4 +- .../get/get_maintenance_window_route.test.ts | 4 +- ...t_active_maintenance_windows_route.test.ts | 2 +- .../update_maintenance_window_route.test.ts | 4 +- .../aggregate/aggregate_rules_route.test.ts | 2 +- .../bulk_delete_rules_route.test.ts | 2 +- .../bulk_disable_rules_route.test.ts | 2 +- .../bulk_edit/bulk_edit_rules_route.test.ts | 2 +- .../bulk_enable_rules_route.test.ts | 2 +- .../rule/apis/clone/clone_rule_route.test.ts | 2 +- .../apis/create/create_rule_route.test.ts | 2 +- .../rule/apis/find/find_rules_route.test.ts | 2 +- .../rule/apis/get/get_rule_route.test.ts | 2 +- .../apis/resolve/resolve_rule_route.test.ts | 2 +- .../rule/apis/tags/get_rule_tags.test.ts | 2 +- .../apis/update/update_rule_route.test.ts | 2 +- .../alerting/server/routes/rule_types.test.ts | 2 +- .../lib/add_generated_action_values.test.ts | 2 +- .../tests/get_action_error_log.test.ts | 6 +- .../tests/get_alert_summary.test.ts | 6 +- .../tests/get_execution_log.test.ts | 14 +- .../rules_client/tests/update_api_key.test.ts | 2 +- .../server/task_runner/task_runner.ts | 2 +- x-pack/plugins/alerting/server/usage/task.ts | 2 +- x-pack/plugins/canvas/server/plugin.ts | 2 +- .../canvas/server/routes/shareables/zip.ts | 2 +- .../server/authorization/authorization.ts | 2 +- ...able_state_and_external_references.test.ts | 4 +- .../plugins/cases/server/telemetry/index.ts | 2 +- .../cloud_defend/server/lib/fleet_util.ts | 12 +- x-pack/plugins/cloud_defend/server/plugin.ts | 33 +-- .../fleet_integration/fleet_integration.ts | 12 +- .../cloud_security_posture/server/plugin.ts | 168 +++++++------- .../server/routes/setup_routes.ts | 2 +- .../server/plugin.ts | 2 +- .../data_stream/results_data_stream.test.ts | 4 +- .../server/plugin.ts | 16 +- .../server/ai_assistant_service/index.ts | 2 +- .../server/lib/executor.test.ts | 9 +- .../elastic_assistant/server/lib/executor.ts | 2 +- .../execute_custom_llm_chain/index.test.ts | 4 +- .../execute_custom_llm_chain/index.ts | 2 +- .../routes/post_actions_connector_execute.ts | 2 +- .../encrypted_saved_objects/server/mocks.ts | 8 +- .../encrypted_saved_objects/tsconfig.json | 1 + .../lib/enterprise_search_config_api.test.ts | 2 +- .../create_ml_inference_pipeline.test.ts | 4 +- ...t_ml_inference_pipeline_processors.test.ts | 4 +- .../server/lib/ml/fetch_ml_models.test.ts | 4 +- .../ml/get_ml_model_deployment_status.test.ts | 4 +- .../lib/ml/start_ml_model_deployment.test.ts | 4 +- .../lib/ml/start_ml_model_download.test.ts | 4 +- .../get_ml_inference_pipelines.test.ts | 4 +- .../enterprise_search/server/plugin.ts | 6 +- .../app_search/adaptive_relevance.test.ts | 20 +- .../server/routes/app_search/engines.test.ts | 20 +- .../routes/app_search/onboarding.test.ts | 4 +- .../routes/app_search/result_settings.test.ts | 8 +- .../routes/app_search/search_settings.test.ts | 12 +- .../routes/app_search/search_ui.test.ts | 4 +- .../routes/workplace_search/oauth.test.ts | 12 +- .../routes/workplace_search/security.test.ts | 8 +- .../routes/workplace_search/sources.test.ts | 8 +- .../event_log/server/event_log_client.test.ts | 4 +- .../event_log/server/event_logger.test.ts | 4 +- x-pack/plugins/event_log/server/plugin.ts | 17 +- .../server/telemetry/usage_collector.ts | 2 +- x-pack/plugins/fleet/server/plugin.ts | 16 +- x-pack/plugins/fleet/server/routes/index.ts | 2 +- .../services/agent_policy_create.test.ts | 18 +- .../server/services/agents/action_runner.ts | 8 +- .../services/artifacts/artifacts.test.ts | 6 +- .../server/services/download_source.test.ts | 4 +- .../server/services/epm/archive/extract.ts | 6 +- .../epm/kibana/assets/install.test.ts | 2 +- .../epm/packages/_install_package.test.ts | 6 +- .../server/services/epm/packages/install.ts | 2 +- .../services/epm/registry/index.test.ts | 2 +- .../services/epm/registry/requests.test.ts | 4 +- .../fleet/server/services/files/index.test.ts | 4 +- .../fleet/server/services/fleet_proxies.ts | 16 +- .../server/services/fleet_usage_logger.ts | 2 +- .../fleet/server/services/output.test.ts | 6 +- .../server/services/package_policy.test.ts | 6 +- .../security/message_signing_service.ts | 2 +- .../security/uninstall_token_service/index.ts | 4 +- .../fleet/server/telemetry/sender.test.ts | 4 +- .../plugins/fleet/server/telemetry/sender.ts | 18 +- .../license_api_guard/server/license.test.ts | 9 +- .../license_management/server/plugin.ts | 2 +- ...ception_list_items_point_in_time_finder.ts | 4 +- ...ind_exception_list_point_in_time_finder.ts | 4 +- ...ception_list_items_point_in_time_finder.ts | 4 +- .../models/data_recognizer/data_recognizer.ts | 2 +- .../models/job_service/model_snapshots.ts | 2 +- .../json_schema_service.ts | 10 +- x-pack/plugins/ml/server/plugin.ts | 12 +- .../server/kibana_monitoring/bulk_uploader.ts | 23 +- x-pack/plugins/monitoring/server/plugin.ts | 2 +- .../services/connectors_email_service.test.ts | 16 +- .../services/licensed_email_service.test.ts | 4 +- .../apm/server/lib/apm_telemetry/index.ts | 64 +++--- .../create_apm_event_client/index.test.ts | 2 +- .../apm/server/plugin.ts | 24 +- .../settings/agent_configuration/route.ts | 2 +- .../create_or_update_custom_link.test.ts | 8 +- ..._legacy_apm_indices_to_space_aware.test.ts | 4 +- .../asset_manager/server/plugin.ts | 2 +- ...er_inventory_metric_threshold_rule_type.ts | 2 +- .../register_log_threshold_rule_type.ts | 2 +- .../register_metric_threshold_rule_type.ts | 2 +- .../log_entries/log_entries_service.ts | 2 +- .../observability/server/plugin.ts | 2 +- .../bedrock/process_bedrock_stream.ts | 2 +- .../server/service/client/index.test.ts | 3 +- .../profiling/server/plugin.ts | 67 +++--- .../slo/server/plugin.ts | 62 ++--- .../slo/server/routes/register_routes.ts | 4 +- .../slo/server/routes/slo/route.ts | 50 ++--- .../tasks/orphan_summary_cleanup_task.ts | 4 +- .../synthetics/server/lib.ts | 11 +- .../synthetics/server/plugin.ts | 4 +- .../add_monitor/add_monitor_api.ts | 11 +- .../synthetics_monitor/get_all_monitors.ts | 3 +- .../synthetics_private_location.ts | 2 +- .../project_monitor_formatter.ts | 3 +- .../synthetics_monitor_client.ts | 3 +- .../synthetics_service.test.ts | 5 +- .../synthetics_service/synthetics_service.ts | 8 +- .../server/synthetics_service/utils/mocks.ts | 2 +- .../server/telemetry/sender.test.ts | 4 +- .../synthetics/server/telemetry/sender.ts | 17 +- .../uptime/server/legacy_uptime/lib/lib.ts | 2 +- .../create_transforms/create_transforms.ts | 12 +- .../osquery/server/lib/telemetry/receiver.ts | 2 +- .../osquery/server/lib/update_global_packs.ts | 6 +- x-pack/plugins/osquery/server/plugin.ts | 142 ++++++------ .../reporting/server/lib/store/store.test.ts | 2 +- x-pack/plugins/rule_registry/server/plugin.ts | 31 +-- .../resource_installer.test.ts | 6 +- .../server/search_strategy/search_strategy.ts | 4 +- .../server/browsers/chromium/driver.ts | 6 +- .../chromium/driver_factory/index.test.ts | 2 +- .../browsers/chromium/driver_factory/index.ts | 4 +- .../server/formats/pdf/index.ts | 4 +- .../server/lib/notebook_catalog.test.ts | 12 +- .../server/lib/conversational_chain.test.ts | 4 +- .../server/lib/conversational_chain.ts | 2 +- .../search_playground/server/routes.ts | 21 +- .../saved_objects/ensure_authorized.test.ts | 6 +- .../endpoint/lib/artifacts/task.test.ts | 2 +- .../complete_external_actions_task.ts | 6 +- ...plete_external_actions_task_runner.test.ts | 4 +- .../server/endpoint/routes/resolver.ts | 17 +- .../server/endpoint/routes/resolver/events.ts | 3 +- .../endpoint/routes/resolver/tree/handler.ts | 7 +- .../artifacts/unified_manifest_client.ts | 6 +- .../server/endpoint/utils/queue_processor.ts | 2 +- .../fleet_integration.test.ts | 4 +- .../fleet_integration/fleet_integration.ts | 6 +- .../handlers/create_event_filters.ts | 8 +- .../remove_protection_updates_note.ts | 7 +- ...y_create_rule_actions_saved_object.test.ts | 12 +- ...gacy_get_rule_actions_saved_object.test.ts | 4 +- .../rule_preview/api/preview_rules/route.ts | 2 +- ...dule_notification_response_actions.test.ts | 8 +- .../schedule_notification_response_actions.ts | 35 +-- .../asset_criticality_data_client.test.ts | 12 +- .../risk_score/tasks/risk_scoring_task.ts | 2 +- .../product_features_service.test.ts | 20 +- .../server/lib/telemetry/receiver.ts | 2 +- .../server/lib/telemetry/sender.ts | 17 +- .../server/lib/telemetry/task_metrics.test.ts | 10 +- .../lib/telemetry/tasks/configuration.ts | 6 +- .../lib/telemetry/tasks/detection_rule.ts | 6 +- .../server/lib/telemetry/tasks/diagnostic.ts | 6 +- .../server/lib/telemetry/tasks/endpoint.ts | 4 +- .../server/lib/telemetry/tasks/filterlists.ts | 6 +- .../telemetry/tasks/prebuilt_rule_alerts.ts | 10 +- .../lib/telemetry/tasks/security_lists.ts | 4 +- .../server/lib/telemetry/tasks/timelines.ts | 6 +- .../telemetry/tasks/timelines_diagnostic.ts | 6 +- .../routes/timelines/copy_timeline/index.ts | 2 +- .../security_solution/server/plugin.ts | 211 ++++++++++-------- .../server/usage/queries/get_case_comments.ts | 2 +- .../usage/queries/get_detection_rules.ts | 2 +- .../usage/queries/legacy_get_rule_actions.ts | 2 +- .../server/plugin.ts | 28 ++- .../server/lib/indices/fetch_index.test.ts | 20 +- .../serverless_search/server/plugin.ts | 35 ++- .../server/routes/api_key_routes.ts | 4 +- .../server/routes/indices_routes.ts | 3 +- .../create_default_space.test.ts | 4 +- .../routes/api/external/copy_to_space.ts | 44 ++-- .../external/disable_legacy_url_aliases.ts | 12 +- .../spaces_client/spaces_client.test.ts | 8 +- .../lib/get_shape_filters.test.ts | 4 +- .../connector_types/servicenow_sir/service.ts | 2 +- .../server/buffered_task_store.test.ts | 2 +- .../server/lib/bulk_operation_buffer.test.ts | 81 +++---- .../server/lib/remove_if_exists.test.ts | 2 +- .../server/lib/result_type.test.ts | 4 +- .../server/metrics/task_metrics_collector.ts | 2 +- x-pack/plugins/task_manager/server/mocks.ts | 2 +- .../server/polling/task_poller.ts | 4 +- .../plugins/task_manager/server/task_pool.ts | 22 +- .../server/task_scheduling.test.ts | 9 +- .../task_manager/server/task_scheduling.ts | 8 +- .../threat_intelligence/server/plugin.ts | 2 +- x-pack/plugins/timelines/server/plugin.ts | 2 +- x-pack/plugins/transform/server/plugin.ts | 57 +++-- .../api/audit_messages/register_route.ts | 15 +- .../api/delete_transforms/register_route.ts | 11 +- .../route_handler_factory.ts | 5 +- .../api/field_histograms/register_route.ts | 11 +- .../reauthorize_transforms/register_route.ts | 11 +- .../route_handler_factory.ts | 4 +- .../api/reset_transforms/register_route.ts | 9 +- .../schedule_now_transforms/register_route.ts | 9 +- .../api/start_transforms/register_route.ts | 9 +- .../api/stop_transforms/register_route.ts | 9 +- .../api/transforms_all/register_route.ts | 13 +- .../api/transforms_create/register_route.ts | 15 +- .../route_handler_factory.ts | 4 +- .../api/transforms_nodes/register_route.ts | 11 +- .../transforms_nodes/route_handler_factory.ts | 5 +- .../api/transforms_preview/register_route.ts | 9 +- .../api/transforms_single/register_route.ts | 11 +- .../transforms_stats_all/register_route.ts | 15 +- .../transforms_stats_single/register_route.ts | 13 +- .../api/transforms_update/register_route.ts | 13 +- x-pack/plugins/transform/server/types.ts | 8 +- .../transform/server/usage/collector.ts | 7 +- .../server/data/lib/time_series_query.test.ts | 2 +- .../triggers_actions_ui/server/plugin.ts | 17 +- .../server/routes/config.test.ts | 4 +- .../server/routes/config.ts | 4 +- .../server/lib/reindexing/worker.ts | 37 +-- .../upgrade_assistant/server/plugin.ts | 2 +- .../plugins/kibana_cors_test/server/plugin.ts | 4 +- .../server/init_routes.ts | 4 +- 345 files changed, 1664 insertions(+), 1430 deletions(-) diff --git a/examples/response_stream/server/plugin.ts b/examples/response_stream/server/plugin.ts index 9620a58ae517b..6bb0c55003059 100644 --- a/examples/response_stream/server/plugin.ts +++ b/examples/response_stream/server/plugin.ts @@ -27,7 +27,7 @@ export class ResponseStreamPlugin implements Plugin { public setup(core: CoreSetup, plugins: ResponseStreamSetupPlugins) { const router = core.http.createRouter(); - core.getStartServices().then(([_, depsStart]) => { + void core.getStartServices().then(([_, depsStart]) => { defineReducerStreamRoute(router, this.logger); defineSimpleStringStreamRoute(router, this.logger); }); diff --git a/examples/response_stream/server/routes/reducer_stream.ts b/examples/response_stream/server/routes/reducer_stream.ts index 5e03cd0732e74..02606b8c44756 100644 --- a/examples/response_stream/server/routes/reducer_stream.ts +++ b/examples/response_stream/server/routes/reducer_stream.ts @@ -85,44 +85,45 @@ export const defineReducerStreamRoute = (router: IRouter, logger: Logger) => { let progress = 0; async function pushStreamUpdate() { - setTimeout(() => { - try { - progress++; - - if (progress > 100 || shouldStop) { - end(); - return; - } - - push(updateProgressAction(progress)); - - const randomEntity = entities[Math.floor(Math.random() * entities.length)]; - const randomAction = actions[Math.floor(Math.random() * actions.length)]; - - if (randomAction === 'add') { - const randomCommits = Math.floor(Math.random() * 100); - push(addToEntityAction(randomEntity, randomCommits)); - } else if (randomAction === 'delete') { - push(deleteEntityAction(randomEntity)); - } else if (randomAction === 'throw-error') { - // Throw an error. It should not crash Kibana! - // It should be caught and logged to the Kibana server console. - throw new Error('There was a (simulated) server side error!'); - } else if (randomAction === 'emit-error') { - // Emit an error as a stream action. - push(errorAction('(Simulated) error pushed to the stream')); - return; - } - - pushStreamUpdate(); - } catch (e) { - logger.error(e); + await new Promise((resolve) => + setTimeout(resolve, Math.floor(Math.random() * maxTimeoutMs)) + ); + try { + progress++; + + if (progress > 100 || shouldStop) { + end(); + return; } - }, Math.floor(Math.random() * maxTimeoutMs)); + + push(updateProgressAction(progress)); + + const randomEntity = entities[Math.floor(Math.random() * entities.length)]; + const randomAction = actions[Math.floor(Math.random() * actions.length)]; + + if (randomAction === 'add') { + const randomCommits = Math.floor(Math.random() * 100); + push(addToEntityAction(randomEntity, randomCommits)); + } else if (randomAction === 'delete') { + push(deleteEntityAction(randomEntity)); + } else if (randomAction === 'throw-error') { + // Throw an error. It should not crash Kibana! + // It should be caught and logged to the Kibana server console. + throw new Error('There was a (simulated) server side error!'); + } else if (randomAction === 'emit-error') { + // Emit an error as a stream action. + push(errorAction('(Simulated) error pushed to the stream')); + return; + } + + void pushStreamUpdate(); + } catch (e) { + logger.error(e); + } } // do not call this using `await` so it will run asynchronously while we return the stream already. - pushStreamUpdate(); + void pushStreamUpdate(); return response.ok(responseWithHeaders); } diff --git a/examples/response_stream/server/routes/single_string_stream.ts b/examples/response_stream/server/routes/single_string_stream.ts index 26c26f0fc6b66..d9cb65686b71e 100644 --- a/examples/response_stream/server/routes/single_string_stream.ts +++ b/examples/response_stream/server/routes/single_string_stream.ts @@ -67,7 +67,7 @@ export const defineSimpleStringStreamRoute = (router: IRouter, logger: Logger) = await timeout(Math.floor(Math.random() * maxTimeoutMs)); if (!shouldStop) { - pushStreamUpdate(); + void pushStreamUpdate(); } } else { end(); @@ -78,7 +78,7 @@ export const defineSimpleStringStreamRoute = (router: IRouter, logger: Logger) = } // do not call this using `await` so it will run asynchronously while we return the stream already. - pushStreamUpdate(); + void pushStreamUpdate(); return response.ok(responseWithHeaders); } diff --git a/examples/search_examples/server/plugin.ts b/examples/search_examples/server/plugin.ts index 57a8b055f9b44..27680a3287aba 100644 --- a/examples/search_examples/server/plugin.ts +++ b/examples/search_examples/server/plugin.ts @@ -48,7 +48,7 @@ export class SearchExamplesPlugin this.logger.debug('search_examples: Setup'); const router = core.http.createRouter(); - core.getStartServices().then(([_, depsStart]) => { + void core.getStartServices().then(([_, depsStart]) => { const myStrategy = mySearchStrategyProvider(depsStart.data); const fibonacciStrategy = fibonacciStrategyProvider(); deps.data.search.registerSearchStrategy('myStrategy', myStrategy); diff --git a/src/core/server/integration_tests/http/cookie_session_storage.test.ts b/src/core/server/integration_tests/http/cookie_session_storage.test.ts index 90343da759ccb..4a71502db0ccb 100644 --- a/src/core/server/integration_tests/http/cookie_session_storage.test.ts +++ b/src/core/server/integration_tests/http/cookie_session_storage.test.ts @@ -439,7 +439,7 @@ describe('Cookie based SessionStorage', () => { await server.preboot(prebootDeps); const { server: innerServer } = await server.setup(setupDeps); - expect( + await expect( createCookieSessionStorageFactory(logger.get(), innerServer, { ...cookieOptions, sameSite: 'None', diff --git a/src/core/server/integration_tests/http/oas.test.ts b/src/core/server/integration_tests/http/oas.test.ts index d0adbb0d29ea7..602b9c76cefa2 100644 --- a/src/core/server/integration_tests/http/oas.test.ts +++ b/src/core/server/integration_tests/http/oas.test.ts @@ -67,7 +67,7 @@ afterEach(async () => { it('is disabled by default', async () => { const server = await startService(); - supertest(server.listener).get('/api/oas').expect(404); + await supertest(server.listener).get('/api/oas').expect(404); }); it('handles requests when enabled', async () => { diff --git a/src/core/server/integration_tests/http/router.test.ts b/src/core/server/integration_tests/http/router.test.ts index 42cd093244a48..e7640e39c3263 100644 --- a/src/core/server/integration_tests/http/router.test.ts +++ b/src/core/server/integration_tests/http/router.test.ts @@ -333,15 +333,15 @@ describe('Options', () => { let i = 0; const intervalId = setInterval(() => { if (i < body.length) { - request.write(body[i++]); + void request.write(body[i++]); } else { clearInterval(intervalId); - request.end((err, res) => { + void request.end((err, res) => { resolve(res); }); } }, interval); - request.on('error', (err) => { + void request.on('error', (err) => { clearInterval(intervalId); reject(err); }); diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/cleanup.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/cleanup.test.ts index 026eaa462aa54..7f04f37589f69 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/cleanup.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/cleanup.test.ts @@ -131,13 +131,13 @@ const setupBaseline = async () => { // inject corrupt saved objects directly using esClient await Promise.all( - savedObjects.map((savedObject) => { + savedObjects.map((savedObject) => client.create({ index: defaultKibanaIndex, refresh: 'wait_for', ...savedObject, - }); - }) + }) + ) ); return client; diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts index 7a2a8b06c9b1c..2b6c7136519ff 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts @@ -425,7 +425,7 @@ describe('migration actions', () => { const redStatusResponse = await client.cluster.health({ index: 'red_then_yellow_index' }); expect(redStatusResponse.status).toBe('red'); - client.indices.putSettings({ + void client.indices.putSettings({ index: 'red_then_yellow_index', body: { // Enable all shard allocation so that the index status turns yellow @@ -574,7 +574,7 @@ describe('migration actions', () => { let indexGreen = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'clone_red_then_green_index', body: { // Enable all shard allocation so that the index status goes green @@ -1844,7 +1844,7 @@ describe('migration actions', () => { let indexYellow = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'red_then_yellow_index', body: { // Renable allocation so that the status becomes yellow @@ -1897,7 +1897,7 @@ describe('migration actions', () => { let indexGreen = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'yellow_then_green_index', body: { // Set 0 replican so that this index becomes green diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions_test_suite.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions_test_suite.ts index a16041a73011e..c114293823cb7 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions_test_suite.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions_test_suite.ts @@ -464,7 +464,7 @@ export const runActionTestSuite = ({ const redStatusResponse = await client.cluster.health({ index: 'red_then_yellow_index' }); expect(redStatusResponse.status).toBe('red'); - client.indices.putSettings({ + void client.indices.putSettings({ index: 'red_then_yellow_index', body: { // Enable all shard allocation so that the index status turns yellow @@ -619,7 +619,7 @@ export const runActionTestSuite = ({ let indexGreen = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'clone_red_then_green_index', body: { // Enable all shard allocation so that the index status goes green @@ -1898,7 +1898,7 @@ export const runActionTestSuite = ({ let indexYellow = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'red_then_yellow_index', body: { // Renable allocation so that the status becomes yellow @@ -1951,7 +1951,7 @@ export const runActionTestSuite = ({ let indexGreen = false; setTimeout(() => { - client.indices.putSettings({ + void client.indices.putSettings({ index: 'yellow_then_green_index', body: { // Set 0 replican so that this index becomes green diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/default_search_fields.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/default_search_fields.test.ts index 4101c22c23d50..52a1d68255332 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/default_search_fields.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/default_search_fields.test.ts @@ -11,9 +11,9 @@ import { createRoot } from '@kbn/core-test-helpers-kbn-server'; describe('SO default search fields', () => { let root: ReturnType; - afterEach(() => { + afterEach(async () => { try { - root?.shutdown(); + await root?.shutdown(); } catch (e) { /* trap */ } diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/split_failed_to_clone.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/split_failed_to_clone.test.ts index 1642e4059a885..306c91aae5902 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/split_failed_to_clone.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/split_failed_to_clone.test.ts @@ -132,14 +132,14 @@ describe.skip('when splitting .kibana into multiple indices and one clone fails' }); // cause a failure when cloning .kibana_slow_clone_* indices - client.cluster.putSettings({ persistent: { 'cluster.max_shards_per_node': 15 } }); + void client.cluster.putSettings({ persistent: { 'cluster.max_shards_per_node': 15 } }); await expect(runMigrationsWhichFailsWhenCloning()).rejects.toThrowError( /cluster_shard_limit_exceeded/ ); // remove the failure - client.cluster.putSettings({ persistent: { 'cluster.max_shards_per_node': 20 } }); + void client.cluster.putSettings({ persistent: { 'cluster.max_shards_per_node': 20 } }); const { runMigrations: runMigrations2ndTime } = await migratorTestKitFactory(); await runMigrations2ndTime(); diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts index 6b3d97206a094..43f0d03b86552 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts @@ -149,9 +149,9 @@ const previouslyRegisteredTypes = [ describe('SO type registrations', () => { let root: ReturnType; - afterEach(() => { + afterEach(async () => { try { - root?.shutdown(); + await root?.shutdown(); } catch (e) { /* trap */ } diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/wait_for_migration_completion.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/wait_for_migration_completion.test.ts index 7d2a2bf8145cf..459cfc921badf 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/wait_for_migration_completion.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/wait_for_migration_completion.test.ts @@ -60,7 +60,7 @@ describe('migration with waitForCompletion=true', () => { await root.preboot(); await root.setup(); - root.start(); + void root.start(); const esClient = esServer.es.getClient(); await retryAsync( diff --git a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts index db89ae88068fb..1440d6d9d91d3 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts @@ -123,7 +123,7 @@ export const getEsClient = async ({ // configure logging system const loggingConf = await firstValueFrom(configService.atPath('logging')); - loggingSystem.upgrade(loggingConf); + await loggingSystem.upgrade(loggingConf); return await getElasticsearchClient(configService, loggerFactory, kibanaVersion); }; @@ -148,7 +148,7 @@ export const getKibanaMigratorTestKit = async ({ // configure logging system const loggingConf = await firstValueFrom(configService.atPath('logging')); - loggingSystem.upgrade(loggingConf); + await loggingSystem.upgrade(loggingConf); const rawClient = await getElasticsearchClient(configService, loggerFactory, kibanaVersion); const client = clientWrapperFactory ? clientWrapperFactory(rawClient) : rawClient; @@ -568,7 +568,7 @@ export const getCurrentVersionTypeRegistry = async ({ await root.preboot(); const coreSetup = await root.setup(); const typeRegistry = coreSetup.savedObjects.getTypeRegistry(); - root.shutdown(); // do not await for it, or we might block the tests + void root.shutdown(); // do not await for it, or we might block the tests return typeRegistry; }; diff --git a/src/core/server/integration_tests/saved_objects/validation/validator.test.ts b/src/core/server/integration_tests/saved_objects/validation/validator.test.ts index 63909b14c290f..a0dc22440f1df 100644 --- a/src/core/server/integration_tests/saved_objects/validation/validator.test.ts +++ b/src/core/server/integration_tests/saved_objects/validation/validator.test.ts @@ -186,7 +186,7 @@ describe.skip('validates saved object types when a schema is provided', () => { }); it('is superseded by migration errors and does not run if a migration fails', async () => { - expect(async () => { + await expect(async () => { await savedObjectsClient.create( 'migration-error', { @@ -233,7 +233,7 @@ describe.skip('validates saved object types when a schema is provided', () => { describe('when validating with a config schema', () => { it('throws when an invalid attribute is provided', async () => { - expect(async () => { + await expect(async () => { await savedObjectsClient.create( 'schema-using-kbn-config', { diff --git a/src/dev/eslint/types.eslint.config.template.js b/src/dev/eslint/types.eslint.config.template.js index 08cbaf3b02325..db17de6f08e3e 100644 --- a/src/dev/eslint/types.eslint.config.template.js +++ b/src/dev/eslint/types.eslint.config.template.js @@ -24,4 +24,14 @@ module.exports = { rules: { '@typescript-eslint/consistent-type-exports': 'error', }, + overrides: [ + { + files: ['server/**/*'], + rules: { + // Let's focus on server-side errors first to avoid server crashes. + // We'll tackle /public eventually. + '@typescript-eslint/no-floating-promises': 'error', + }, + }, + ], }; diff --git a/src/plugins/content_management/server/core/core.test.ts b/src/plugins/content_management/server/core/core.test.ts index 2eafd1dc4df91..075eb6a383e8b 100644 --- a/src/plugins/content_management/server/core/core.test.ts +++ b/src/plugins/content_management/server/core/core.test.ts @@ -309,7 +309,7 @@ describe('Content Core', () => { { title: 'Hello' }, { id: '1234' } // We send this "id" option to specify the id of the content created ); - expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ + await expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ contentTypeId: FOO_CONTENT_ID, result: { item: { @@ -327,7 +327,7 @@ describe('Content Core', () => { await fooContentCrud!.create(ctx, { title: 'Hello' }, { id: '1234' }); await fooContentCrud!.update(ctx, '1234', { title: 'changed' }); - expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ + await expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ contentTypeId: FOO_CONTENT_ID, result: { item: { @@ -363,7 +363,7 @@ describe('Content Core', () => { }, }); - expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ + await expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ contentTypeId: FOO_CONTENT_ID, result: { item: { @@ -380,14 +380,14 @@ describe('Content Core', () => { const { fooContentCrud, ctx, cleanUp } = setup({ registerFooType: true }); await fooContentCrud!.create(ctx, { title: 'Hello' }, { id: '1234' }); - expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ + await expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ contentTypeId: FOO_CONTENT_ID, result: { item: expect.any(Object), }, }); await fooContentCrud!.delete(ctx, '1234'); - expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ + await expect(fooContentCrud!.get(ctx, '1234')).resolves.toEqual({ contentTypeId: FOO_CONTENT_ID, result: { item: undefined, diff --git a/src/plugins/content_management/server/rpc/procedures/bulk_get.test.ts b/src/plugins/content_management/server/rpc/procedures/bulk_get.test.ts index baeb9c08471c7..d79af15b136d2 100644 --- a/src/plugins/content_management/server/rpc/procedures/bulk_get.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/bulk_get.test.ts @@ -264,16 +264,16 @@ describe('RPC -> bulkGet()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => fn(ctx, { contentTypeId: 'unknown', ids: ['123', '456'] })).rejects.toEqual( - new Error('Content [unknown] is not registered.') - ); + await expect(() => + fn(ctx, { contentTypeId: 'unknown', ids: ['123', '456'] }) + ).rejects.toEqual(new Error('Content [unknown] is not registered.')); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, ids: ['123', '456'], @@ -284,9 +284,9 @@ describe('RPC -> bulkGet()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { contentTypeId: FOO_CONTENT_ID, ids: ['1234'], version: 1 }); + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, ids: ['1234'], version: 1 }); const [[storageContext]] = storage.bulkGet.mock.calls; // getTransforms() utils should be available from context diff --git a/src/plugins/content_management/server/rpc/procedures/create.test.ts b/src/plugins/content_management/server/rpc/procedures/create.test.ts index ec877d2ea0d0d..5bf8a63462f69 100644 --- a/src/plugins/content_management/server/rpc/procedures/create.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/create.test.ts @@ -230,16 +230,16 @@ describe('RPC -> create()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: 'unknown', data: { title: 'Hello' } }) ).rejects.toEqual(new Error('Content [unknown] is not registered.')); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, data: { title: 'Hello' }, @@ -250,9 +250,9 @@ describe('RPC -> create()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { contentTypeId: FOO_CONTENT_ID, data: { title: 'Hello' }, version: 1 }); + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, data: { title: 'Hello' }, version: 1 }); const [[storageContext]] = storage.create.mock.calls; // getTransforms() utils should be available from context diff --git a/src/plugins/content_management/server/rpc/procedures/delete.test.ts b/src/plugins/content_management/server/rpc/procedures/delete.test.ts index 5becd91a7b7d4..0d9089eecc19b 100644 --- a/src/plugins/content_management/server/rpc/procedures/delete.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/delete.test.ts @@ -210,16 +210,16 @@ describe('RPC -> delete()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => fn(ctx, { contentTypeId: 'unknown', id: '1234' })).rejects.toEqual( + await expect(() => fn(ctx, { contentTypeId: 'unknown', id: '1234' })).rejects.toEqual( new Error('Content [unknown] is not registered.') ); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', @@ -230,9 +230,9 @@ describe('RPC -> delete()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', version: 1 }); + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', version: 1 }); const [[storageContext]] = storage.delete.mock.calls; // getTransforms() utils should be available from context diff --git a/src/plugins/content_management/server/rpc/procedures/get.test.ts b/src/plugins/content_management/server/rpc/procedures/get.test.ts index 83affb9e725ae..6a304c325cd13 100644 --- a/src/plugins/content_management/server/rpc/procedures/get.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/get.test.ts @@ -215,16 +215,16 @@ describe('RPC -> get()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => fn(ctx, { contentTypeId: 'unknown', id: '1234' })).rejects.toEqual( + await expect(() => fn(ctx, { contentTypeId: 'unknown', id: '1234' })).rejects.toEqual( new Error('Content [unknown] is not registered.') ); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', @@ -235,9 +235,9 @@ describe('RPC -> get()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', version: 1 }); + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '1234', version: 1 }); const [[storageContext]] = storage.get.mock.calls; // getTransforms() utils should be available from context diff --git a/src/plugins/content_management/server/rpc/procedures/msearch.test.ts b/src/plugins/content_management/server/rpc/procedures/msearch.test.ts index 7b28fae6d3b49..0cf899a59ae36 100644 --- a/src/plugins/content_management/server/rpc/procedures/msearch.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/msearch.test.ts @@ -245,9 +245,9 @@ describe('RPC -> mSearch()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypes: [{ contentTypeId: 'unknown', version: 1 }], query: { text: 'Hello' }, @@ -255,9 +255,9 @@ describe('RPC -> mSearch()', () => { ).rejects.toEqual(new Error('Content [unknown] is not registered.')); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypes: [{ contentTypeId: 'foo', version: 7 }], query: { text: 'Hello' }, diff --git a/src/plugins/content_management/server/rpc/procedures/search.test.ts b/src/plugins/content_management/server/rpc/procedures/search.test.ts index 2d7ef1501d102..0ee18e68d2299 100644 --- a/src/plugins/content_management/server/rpc/procedures/search.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/search.test.ts @@ -247,16 +247,16 @@ describe('RPC -> search()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: 'unknown', query: { text: 'Hello' } }) ).rejects.toEqual(new Error('Content [unknown] is not registered.')); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, query: { text: 'Hello' }, @@ -267,9 +267,9 @@ describe('RPC -> search()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { contentTypeId: FOO_CONTENT_ID, query: { text: 'Hello' }, version: 1 }); + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, query: { text: 'Hello' }, version: 1 }); const [[storageContext]] = storage.search.mock.calls; // getTransforms() utils should be available from context diff --git a/src/plugins/content_management/server/rpc/procedures/update.test.ts b/src/plugins/content_management/server/rpc/procedures/update.test.ts index ad721d045be1d..48d8a846961a5 100644 --- a/src/plugins/content_management/server/rpc/procedures/update.test.ts +++ b/src/plugins/content_management/server/rpc/procedures/update.test.ts @@ -240,16 +240,16 @@ describe('RPC -> update()', () => { }); describe('validation', () => { - test('should validate that content type definition exist', () => { + test('should validate that content type definition exist', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: 'unknown', id: '123', data: { title: 'Hello' } }) ).rejects.toEqual(new Error('Content [unknown] is not registered.')); }); - test('should throw if the request version is higher than the registered version', () => { + test('should throw if the request version is higher than the registered version', async () => { const { ctx } = setup(); - expect(() => + await expect(() => fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '123', @@ -261,9 +261,9 @@ describe('RPC -> update()', () => { }); describe('object versioning', () => { - test('should expose a utility to transform and validate services objects', () => { + test('should expose a utility to transform and validate services objects', async () => { const { ctx, storage } = setup(); - fn(ctx, { + await fn(ctx, { contentTypeId: FOO_CONTENT_ID, id: '123', version: 1, diff --git a/src/plugins/content_management/server/rpc/rpc_service.test.ts b/src/plugins/content_management/server/rpc/rpc_service.test.ts index 0ac81a3c3fa8f..197c1f257b585 100644 --- a/src/plugins/content_management/server/rpc/rpc_service.test.ts +++ b/src/plugins/content_management/server/rpc/rpc_service.test.ts @@ -11,21 +11,21 @@ import { ProcedureDefinition, RpcService } from './rpc_service'; describe('RpcService', () => { describe('register()', () => { - test('should register a procedure', () => { + test('should register a procedure', async () => { const rpc = new RpcService<{}, 'foo'>(); const fn = jest.fn(); const procedure: ProcedureDefinition<{}> = { fn }; rpc.register('foo', procedure); const context = {}; - rpc.call(context, 'foo'); + await rpc.call(context, 'foo'); expect(fn).toHaveBeenCalledWith(context, undefined); }); }); describe('call()', () => { - test('should require a schema if an input is passed', () => { + test('should require a schema if an input is passed', async () => { const rpc = new RpcService<{}, 'foo'>(); const fn = jest.fn(); const procedure: ProcedureDefinition<{}> = { fn }; @@ -34,7 +34,7 @@ describe('RpcService', () => { const context = {}; const input = { foo: 'bar' }; - expect(() => { + await expect(() => { return rpc.call(context, 'foo', input); }).rejects.toEqual(new Error('Input schema missing for [foo] procedure.')); }); @@ -60,15 +60,15 @@ describe('RpcService', () => { expect(result).toEqual(output); }); - test('should throw an error if the procedure is not registered', () => { + test('should throw an error if the procedure is not registered', async () => { const rpc = new RpcService(); - expect(() => { + await expect(() => { return rpc.call(undefined, 'unknown'); }).rejects.toEqual(new Error('Procedure [unknown] is not registered.')); }); - test('should validate that the input is valid', () => { + test('should validate that the input is valid', async () => { const rpc = new RpcService<{}, 'foo'>(); const fn = jest.fn(); @@ -81,12 +81,12 @@ describe('RpcService', () => { const context = {}; const input = { bad: 'unknown prop' }; - expect(() => { + await expect(() => { return rpc.call(context, 'foo', input); }).rejects.toEqual(new Error('[foo]: expected value of type [string] but got [undefined]')); }); - test('should validate the output if schema is provided', () => { + test('should validate the output if schema is provided', async () => { const rpc = new RpcService<{}, 'foo'>(); const fn = jest.fn().mockResolvedValue({ bad: 'unknown prop' }); @@ -97,7 +97,7 @@ describe('RpcService', () => { rpc.register('foo', procedure); const context = {}; - expect(() => { + await expect(() => { return rpc.call(context, 'foo'); }).rejects.toEqual(new Error('[foo]: expected value of type [string] but got [undefined]')); }); diff --git a/src/plugins/data/server/query/route_handler_context.test.ts b/src/plugins/data/server/query/route_handler_context.test.ts index 5976db550f182..d2a9a14fe1fce 100644 --- a/src/plugins/data/server/query/route_handler_context.test.ts +++ b/src/plugins/data/server/query/route_handler_context.test.ts @@ -207,12 +207,12 @@ describe('saved query route handler context', () => { const response = context.create(savedQueryAttributes); - expect(response).rejects.toMatchInlineSnapshot(`[Error: An Error]`); + await expect(response).rejects.toMatchInlineSnapshot(`[Error: An Error]`); }); it('should throw an error if the saved query does not have a title', async () => { const response = context.create({ ...savedQueryAttributes, title: '' }); - expect(response).rejects.toMatchInlineSnapshot( + await expect(response).rejects.toMatchInlineSnapshot( `[Error: Cannot create query without a title]` ); }); @@ -266,12 +266,12 @@ describe('saved query route handler context', () => { const response = context.update('foo', savedQueryAttributes); - expect(response).rejects.toMatchInlineSnapshot(`[Error: An Error]`); + await expect(response).rejects.toMatchInlineSnapshot(`[Error: An Error]`); }); it('should throw an error if the saved query does not have a title', async () => { const response = context.create({ ...savedQueryAttributes, title: '' }); - expect(response).rejects.toMatchInlineSnapshot( + await expect(response).rejects.toMatchInlineSnapshot( `[Error: Cannot create query without a title]` ); }); @@ -609,7 +609,7 @@ describe('saved query route handler context', () => { }); const result = context.get('food'); - expect(result).rejects.toMatchInlineSnapshot( + await expect(result).rejects.toMatchInlineSnapshot( `[Error: Multiple saved queries found with ID: food (legacy URL alias conflict)]` ); }); diff --git a/src/plugins/data/server/search/collectors/search/usage.ts b/src/plugins/data/server/search/collectors/search/usage.ts index 65eafd28538e3..50d71fbc8ddff 100644 --- a/src/plugins/data/server/search/collectors/search/usage.ts +++ b/src/plugins/data/server/search/collectors/search/usage.ts @@ -88,11 +88,11 @@ export function searchUsageObserver( next(response: IEsSearchResponse) { if (isRestore || isRunningResponse(response)) return; logger.debug(`trackSearchStatus:success, took:${response.rawResponse.took}`); - usage?.trackSuccess(response.rawResponse.took); + void usage?.trackSuccess(response.rawResponse.took); }, error(e: Error) { logger.debug(`trackSearchStatus:error, ${e}`); - usage?.trackError(); + void usage?.trackError(); }, }; } diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index ad4dec61cab7c..12b84ca0c5694 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -256,7 +256,7 @@ export class SearchService implements Plugin { registerFunction: expressions.registerFunction, }); - firstValueFrom(this.initializerContext.config.create()).then((value) => { + void firstValueFrom(this.initializerContext.config.create()).then((value) => { if (value.search.aggs.shardDelay.enabled) { aggs.types.registerBucket(SHARD_DELAY_AGG_NAME, getShardDelayBucketAgg); expressions.registerFunction(aggShardDelay); diff --git a/src/plugins/data/server/search/session/session_service.test.ts b/src/plugins/data/server/search/session/session_service.test.ts index 481fabcfa423e..212eb810f227e 100644 --- a/src/plugins/data/server/search/session/session_service.test.ts +++ b/src/plugins/data/server/search/session/session_service.test.ts @@ -102,31 +102,31 @@ describe('SearchSessionService', () => { expect(savedObjectsClient.create).not.toHaveBeenCalled(); }); - it('Save throws', () => { - expect(() => + it('Save throws', async () => { + await expect(() => service.save({ savedObjectsClient }, mockUser1, sessionId, {}) ).rejects.toBeInstanceOf(Error); }); - it('Update throws', () => { + it('Update throws', async () => { const attributes = { name: 'new_name' }; const response = service.update({ savedObjectsClient }, mockUser1, sessionId, attributes); - expect(response).rejects.toBeInstanceOf(Error); + await expect(response).rejects.toBeInstanceOf(Error); }); - it('Cancel throws', () => { + it('Cancel throws', async () => { const response = service.cancel({ savedObjectsClient }, mockUser1, sessionId); - expect(response).rejects.toBeInstanceOf(Error); + await expect(response).rejects.toBeInstanceOf(Error); }); - it('getId throws', () => { + it('getId throws', async () => { const response = service.getId({ savedObjectsClient }, mockUser1, {}, {}); - expect(response).rejects.toBeInstanceOf(Error); + await expect(response).rejects.toBeInstanceOf(Error); }); - it('Delete throws', () => { + it('Delete throws', async () => { const response = service.delete({ savedObjectsClient }, mockUser1, sessionId); - expect(response).rejects.toBeInstanceOf(Error); + await expect(response).rejects.toBeInstanceOf(Error); }); }); @@ -156,7 +156,7 @@ describe('SearchSessionService', () => { const coreStart = coreMock.createStart(); await flushPromises(); - await service.start(coreStart, {}); + service.start(coreStart, {}); }); afterEach(() => { @@ -164,22 +164,22 @@ describe('SearchSessionService', () => { }); describe('save', () => { - it('throws if `name` is not provided', () => { - expect(() => + it('throws if `name` is not provided', async () => { + await expect(() => service.save({ savedObjectsClient }, mockUser1, sessionId, {}) ).rejects.toMatchInlineSnapshot(`[Error: Name is required]`); }); - it('throws if `appId` is not provided', () => { - expect( + it('throws if `appId` is not provided', async () => { + await expect( service.save({ savedObjectsClient }, mockUser1, sessionId, { name: 'banana', }) ).rejects.toMatchInlineSnapshot(`[Error: AppId is required]`); }); - it('throws if `locatorId` is not provided', () => { - expect( + it('throws if `locatorId` is not provided', async () => { + await expect( service.save({ savedObjectsClient }, mockUser1, sessionId, { name: 'banana', appId: 'nanana', @@ -220,10 +220,10 @@ describe('SearchSessionService', () => { expect(callAttributes).toHaveProperty('username', mockUser1.username); }); - it('throws error if user conflicts', () => { + it('throws error if user conflicts', async () => { savedObjectsClient.get.mockResolvedValue(mockSavedObject); - expect( + await expect( service.get({ savedObjectsClient }, mockUser2, sessionId) ).rejects.toMatchInlineSnapshot(`[Error: Not Found]`); }); @@ -614,7 +614,7 @@ describe('SearchSessionService', () => { expect(callAttributes).toHaveProperty('name', attributes.name); }); - it('throws if user conflicts', () => { + it('throws if user conflicts', async () => { const mockUpdateSavedObject = { ...mockSavedObject, attributes: {}, @@ -623,7 +623,7 @@ describe('SearchSessionService', () => { savedObjectsClient.update.mockResolvedValue(mockUpdateSavedObject); const attributes = { name: 'new_name' }; - expect( + await expect( service.update({ savedObjectsClient }, mockUser2, sessionId, attributes) ).rejects.toMatchInlineSnapshot(`[Error: Not Found]`); }); @@ -659,10 +659,10 @@ describe('SearchSessionService', () => { expect(callAttributes).toHaveProperty('isCanceled', true); }); - it('throws if user conflicts', () => { + it('throws if user conflicts', async () => { savedObjectsClient.get.mockResolvedValue(mockSavedObject); - expect( + await expect( service.cancel({ savedObjectsClient }, mockUser2, sessionId) ).rejects.toMatchInlineSnapshot(`[Error: Not Found]`); }); @@ -803,18 +803,18 @@ describe('SearchSessionService', () => { }); describe('getId', () => { - it('throws if `sessionId` is not provided', () => { + it('throws if `sessionId` is not provided', async () => { const searchRequest = { params: {} }; - expect(() => + await expect(() => service.getId({ savedObjectsClient }, mockUser1, searchRequest, {}) ).rejects.toMatchInlineSnapshot(`[Error: Session ID is required]`); }); - it('throws if there is not a saved object', () => { + it('throws if there is not a saved object', async () => { const searchRequest = { params: {} }; - expect(() => + await expect(() => service.getId({ savedObjectsClient }, mockUser1, searchRequest, { sessionId, isStored: false, @@ -824,10 +824,10 @@ describe('SearchSessionService', () => { ); }); - it('throws if not restoring a saved session', () => { + it('throws if not restoring a saved session', async () => { const searchRequest = { params: {} }; - expect(() => + await expect(() => service.getId({ savedObjectsClient }, mockUser1, searchRequest, { sessionId, isStored: true, diff --git a/src/plugins/data_views/server/expressions/load_index_pattern.test.ts b/src/plugins/data_views/server/expressions/load_index_pattern.test.ts index 94bd854e6734c..2c59a35349912 100644 --- a/src/plugins/data_views/server/expressions/load_index_pattern.test.ts +++ b/src/plugins/data_views/server/expressions/load_index_pattern.test.ts @@ -35,7 +35,7 @@ describe('indexPattern expression function', () => { test('throws if getKibanaRequest is not available', async () => { const indexPatternDefinition = getFunctionDefinition({ getStartDependencies }); - expect(async () => { + await expect(async () => { await indexPatternDefinition().fn(null, { id: '1' }, {} as any); }).rejects.toThrowErrorMatchingInlineSnapshot( `"A KibanaRequest is required to execute this search on the server. Please provide a request object to the expression execution params."` diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts index 0536422476228..99ce0736a9ead 100644 --- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts +++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts @@ -137,7 +137,7 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I } }; -export const registerFields = async ( +export const registerFields = ( router: IRouter, getStartServices: StartServicesAccessor< DataViewsServerPluginStartDependencies, diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts index 439dc6795b682..0daadeaf567c3 100644 --- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts +++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts @@ -207,7 +207,7 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I } }; -export const registerFieldForWildcard = async ( +export const registerFieldForWildcard = ( router: IRouter, getStartServices: StartServicesAccessor< DataViewsServerPluginStartDependencies, diff --git a/src/plugins/data_views/server/rest_api_routes/public/create_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/create_data_view.test.ts index 206ca278a85d7..89e01734977e7 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/create_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/create_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('create data view', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - createDataView({ + await createDataView({ dataViewsService, spec: {}, counterName: 'POST /path', diff --git a/src/plugins/data_views/server/rest_api_routes/public/default_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/default_data_view.test.ts index 9af8688913229..f6ec3861f994f 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/default_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/default_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('default data view', () => { - it('set - calls usageCollection', () => { + it('set - calls usageCollection', async () => { const usageCollection = getUsageCollection(); - setDefault({ + await setDefault({ dataViewsService, counterName: 'POST /path', usageCollection, @@ -23,9 +23,9 @@ describe('default data view', () => { expect(usageCollection.incrementCounter).toBeCalledTimes(1); }); - it('get - calls usageCollection', () => { + it('get - calls usageCollection', async () => { const usageCollection = getUsageCollection(); - getDefault({ + await getDefault({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/delete_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/delete_data_view.test.ts index d1c41e8bc8d47..f3e902fa5be65 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/delete_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/delete_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('delete data view', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - deleteDataView({ + await deleteDataView({ dataViewsService, counterName: 'DELETE /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/fields/update_fields.test.ts b/src/plugins/data_views/server/rest_api_routes/public/fields/update_fields.test.ts index c2ff246568c84..06a4f89b25d85 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/fields/update_fields.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/fields/update_fields.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('create runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -27,7 +27,7 @@ describe('create runtime field', () => { } as unknown as DataViewLazy) ); - updateFields({ + await updateFields({ dataViewsService, counterName: 'POST /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/get_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/get_data_view.test.ts index b035d48072f4c..963e3a64ceeb5 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/get_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/get_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('get default data view', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - getDataView({ + await getDataView({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/get_data_views.test.ts b/src/plugins/data_views/server/rest_api_routes/public/get_data_views.test.ts index d3cd1d68af018..ae5ed06674d15 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/get_data_views.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/get_data_views.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('get all data views', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - getDataViews({ + await getDataViews({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/has_user_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/has_user_data_view.test.ts index fc2f763580e99..d2e549d7ded2b 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/has_user_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/has_user_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('get default data view', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - hasUserDataView({ + await hasUserDataView({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/create_runtime_field.test.ts b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/create_runtime_field.test.ts index 30ba66ec22b55..ba7f59c1b4474 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/create_runtime_field.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/create_runtime_field.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('create runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -28,7 +28,7 @@ describe('create runtime field', () => { } as unknown as DataViewLazy) ); - createRuntimeField({ + await createRuntimeField({ dataViewsService, counterName: 'POST /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/delete_runtime_field.test.ts b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/delete_runtime_field.test.ts index 6f0fb6ab168d8..955fbdff4ffab 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/delete_runtime_field.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/delete_runtime_field.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('delete runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -23,7 +23,7 @@ describe('delete runtime field', () => { } as unknown as DataViewLazy) ); - deleteRuntimeField({ + await deleteRuntimeField({ dataViewsService, counterName: 'DELETE /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/get_runtime_field.test.ts b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/get_runtime_field.test.ts index 8693c78961bfc..c5080a16178fc 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/get_runtime_field.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/get_runtime_field.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('get runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -25,7 +25,7 @@ describe('get runtime field', () => { } as unknown as DataViewLazy) ); - getRuntimeField({ + await getRuntimeField({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/put_runtime_field.test.ts b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/put_runtime_field.test.ts index a0ea59c8e663c..8b0a75d5aa970 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/put_runtime_field.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/put_runtime_field.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('put runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -27,7 +27,7 @@ describe('put runtime field', () => { } as unknown as DataViewLazy) ); - putRuntimeField({ + await putRuntimeField({ dataViewsService, counterName: 'PUT /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/update_runtime_field.test.ts b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/update_runtime_field.test.ts index 69154d89f3a1d..8e70b6ad4bf6e 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/update_runtime_field.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/runtime_fields/update_runtime_field.test.ts @@ -12,7 +12,7 @@ import { getUsageCollection } from '../test_utils'; import { DataViewLazy } from '../../../../common'; describe('update runtime field', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); dataViewsService.getDataViewLazy.mockImplementation( @@ -29,7 +29,7 @@ describe('update runtime field', () => { } as unknown as DataViewLazy) ); - updateRuntimeField({ + await updateRuntimeField({ dataViewsService, counterName: 'POST /path', usageCollection, diff --git a/src/plugins/data_views/server/rest_api_routes/public/update_data_view.test.ts b/src/plugins/data_views/server/rest_api_routes/public/update_data_view.test.ts index 4f4056a6d597a..64ab989457f4c 100644 --- a/src/plugins/data_views/server/rest_api_routes/public/update_data_view.test.ts +++ b/src/plugins/data_views/server/rest_api_routes/public/update_data_view.test.ts @@ -11,9 +11,9 @@ import { dataViewsService } from '../../mocks'; import { getUsageCollection } from './test_utils'; describe('get default data view', () => { - it('call usageCollection', () => { + it('call usageCollection', async () => { const usageCollection = getUsageCollection(); - updateDataView({ + await updateDataView({ dataViewsService, counterName: 'GET /path', usageCollection, diff --git a/src/plugins/discover/server/locator/title_from_locator.test.ts b/src/plugins/discover/server/locator/title_from_locator.test.ts index f3e459a8bf39b..abb0636c32a1f 100644 --- a/src/plugins/discover/server/locator/title_from_locator.test.ts +++ b/src/plugins/discover/server/locator/title_from_locator.test.ts @@ -105,7 +105,7 @@ test(`throws error if DiscoverAppLocatorParams do not contain a saved search ID` return await provider(mockPayload[0].params); }; - expect(testFn).rejects.toEqual( + await expect(testFn).rejects.toEqual( new Error('DiscoverAppLocatorParams must contain a saved search reference') ); }); diff --git a/src/plugins/files/server/routes/file_kind/upload.test.ts b/src/plugins/files/server/routes/file_kind/upload.test.ts index 49a207ea80345..ae85a9e371c47 100644 --- a/src/plugins/files/server/routes/file_kind/upload.test.ts +++ b/src/plugins/files/server/routes/file_kind/upload.test.ts @@ -36,7 +36,7 @@ describe('upload', () => { beforeEach(async () => { ({ ctx, fileService } = createFileKindsRequestHandlerContextMock()); uploadContent = jest.fn(); - deleteFn = jest.fn(); + deleteFn = jest.fn(async () => {}); // We need it to be a promise, or it'll crash because of missing `.catch` fileService.getById.mockResolvedValueOnce({ id: 'test', data: { size: 1 }, diff --git a/src/plugins/files/server/routes/file_kind/upload.ts b/src/plugins/files/server/routes/file_kind/upload.ts index 9a97f685cc85d..74faaf9334fe9 100644 --- a/src/plugins/files/server/routes/file_kind/upload.ts +++ b/src/plugins/files/server/routes/file_kind/upload.ts @@ -76,7 +76,7 @@ export const handler: CreateHandler = async ({ files, fileKind }, req, logger.info( `File (id: ${file.id}) upload aborted. Deleting file due to self-destruct flag.` ); - file.delete(); // fire and forget + file.delete().catch(() => {}); // fire and forget } return res.customError({ body: { message: e.message }, statusCode: 499 }); } diff --git a/src/plugins/kibana_usage_collection/server/collectors/cloud/cloud_provider_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/cloud/cloud_provider_collector.ts index 6939b20f4169c..76f79ed50348a 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/cloud/cloud_provider_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/cloud/cloud_provider_collector.ts @@ -27,7 +27,7 @@ export function registerCloudProviderUsageCollector( const cloudDetector = new CloudDetector(); // determine the cloud service in the background - cloudDetector.detectCloudService(ac.signal); + cloudDetector.detectCloudService(ac.signal).catch(() => {}); const collector = usageCollection.makeUsageCollector({ type: 'cloud_provider', diff --git a/src/plugins/kibana_usage_collection/server/collectors/cloud/detector/cloud_detector.mock.ts b/src/plugins/kibana_usage_collection/server/collectors/cloud/detector/cloud_detector.mock.ts index 82e321c93783d..67697cac87b6c 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/cloud/detector/cloud_detector.mock.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/cloud/detector/cloud_detector.mock.ts @@ -8,7 +8,7 @@ const create = () => { const mock = { - detectCloudService: jest.fn(), + detectCloudService: jest.fn(async () => {}), // We need it to be a promise, or it'll crash because of missing `.catch` getCloudDetails: jest.fn(), }; diff --git a/src/plugins/maps_ems/server/plugin.ts b/src/plugins/maps_ems/server/plugin.ts index ebdc6814fd6eb..255fbaf4f912a 100644 --- a/src/plugins/maps_ems/server/plugin.ts +++ b/src/plugins/maps_ems/server/plugin.ts @@ -38,7 +38,10 @@ export class MapsEmsPlugin implements Plugin { isEnterprisePlus = enterprise.state === 'valid'; } - plugins.licensing.refresh().then(updateLicenseState); + plugins.licensing + .refresh() + .then(updateLicenseState) + .catch(() => {}); plugins.licensing.license$.subscribe(updateLicenseState); } diff --git a/src/plugins/navigation/server/plugin.ts b/src/plugins/navigation/server/plugin.ts index e5d83b915b897..6724ed8c20c53 100644 --- a/src/plugins/navigation/server/plugin.ts +++ b/src/plugins/navigation/server/plugin.ts @@ -36,14 +36,12 @@ export class NavigationServerPlugin if (plugins.cloud?.isCloudEnabled && !this.isServerless()) { const config = this.initializerContext.config.get(); - core.getStartServices().then(([coreStart, deps]) => { - deps.cloudExperiments?.getVariation(SOLUTION_NAV_FEATURE_FLAG_NAME, false).then((value) => { - if (value) { - core.uiSettings.registerGlobal(getUiSettings(config)); - } else { - this.removeUiSettings(coreStart, getUiSettings(config)); - } - }); + void core.getStartServices().then(async ([coreStart, deps]) => { + if (await deps.cloudExperiments?.getVariation(SOLUTION_NAV_FEATURE_FLAG_NAME, false)) { + core.uiSettings.registerGlobal(getUiSettings(config)); + } else { + await this.removeUiSettings(coreStart, getUiSettings(config)); + } }); } diff --git a/x-pack/packages/ml/response_stream/server/stream_factory.test.ts b/x-pack/packages/ml/response_stream/server/stream_factory.test.ts index 4b75cf4e0826a..839e7bfdfb9de 100644 --- a/x-pack/packages/ml/response_stream/server/stream_factory.test.ts +++ b/x-pack/packages/ml/response_stream/server/stream_factory.test.ts @@ -93,7 +93,7 @@ describe('streamFactory', () => { // the browser on the client side will automatically take care of unzipping // without the need for additional custom code. it('should encode and receive a compressed string based stream', (done) => { - (async () => { + void (async () => { const { end, push, responseWithHeaders } = streamFactory( { 'accept-encoding': 'gzip', @@ -133,7 +133,7 @@ describe('streamFactory', () => { }); it('should encode and receive a compressed NDJSON based stream', (done) => { - (async () => { + void (async () => { const { DELIMITER, end, push, responseWithHeaders } = streamFactory( { 'accept-encoding': 'gzip', diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index ac5b3206b722f..b01199b4e7667 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -580,15 +580,17 @@ export class ActionsPlugin implements Plugin { - scheduleActionsTelemetry(this.telemetryLogger, plugins.taskManager); - }); + this.eventLogService!.isEsContextReady() + .then(() => { + scheduleActionsTelemetry(this.telemetryLogger, plugins.taskManager); + }) + .catch(() => {}); if (this.actionsConfig.preconfiguredAlertHistoryEsIndex) { createAlertHistoryIndexTemplate({ client: core.elasticsearch.client.asInternalUser, logger: this.logger, - }); + }).catch(() => {}); } this.validateEnabledConnectorTypes(plugins); diff --git a/x-pack/plugins/actions/server/routes/connector/get/get.test.ts b/x-pack/plugins/actions/server/routes/connector/get/get.test.ts index e191a721a59a9..28293ae7947f2 100644 --- a/x-pack/plugins/actions/server/routes/connector/get/get.test.ts +++ b/x-pack/plugins/actions/server/routes/connector/get/get.test.ts @@ -149,7 +149,7 @@ describe('getConnectorRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/connector/get_all/get_all.test.ts b/x-pack/plugins/actions/server/routes/connector/get_all/get_all.test.ts index 223a2d56c0843..0ab3b57e238cf 100644 --- a/x-pack/plugins/actions/server/routes/connector/get_all/get_all.test.ts +++ b/x-pack/plugins/actions/server/routes/connector/get_all/get_all.test.ts @@ -89,7 +89,7 @@ describe('getAllConnectorsRoute', () => { const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/connector/get_all_system/get_all_system.test.ts b/x-pack/plugins/actions/server/routes/connector/get_all_system/get_all_system.test.ts index 8130c8cd3a809..07221aacddde7 100644 --- a/x-pack/plugins/actions/server/routes/connector/get_all_system/get_all_system.test.ts +++ b/x-pack/plugins/actions/server/routes/connector/get_all_system/get_all_system.test.ts @@ -125,7 +125,7 @@ describe('getAllConnectorsIncludingSystemRoute', () => { const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/connector/list_types/list_types.test.ts b/x-pack/plugins/actions/server/routes/connector/list_types/list_types.test.ts index 91419ac562324..e7370c7638a89 100644 --- a/x-pack/plugins/actions/server/routes/connector/list_types/list_types.test.ts +++ b/x-pack/plugins/actions/server/routes/connector/list_types/list_types.test.ts @@ -241,7 +241,7 @@ describe('listTypesRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/connector/list_types_system/list_types_system.test.ts b/x-pack/plugins/actions/server/routes/connector/list_types_system/list_types_system.test.ts index af6e057cafc9c..07d2d3adcd4f3 100644 --- a/x-pack/plugins/actions/server/routes/connector/list_types_system/list_types_system.test.ts +++ b/x-pack/plugins/actions/server/routes/connector/list_types_system/list_types_system.test.ts @@ -242,7 +242,7 @@ describe('listTypesWithSystemRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/create.test.ts b/x-pack/plugins/actions/server/routes/create.test.ts index dd1317f57cd27..7d9c7fd1a5899 100644 --- a/x-pack/plugins/actions/server/routes/create.test.ts +++ b/x-pack/plugins/actions/server/routes/create.test.ts @@ -172,7 +172,7 @@ describe('createActionRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); }); test('validates body to prevent empty strings', async () => { diff --git a/x-pack/plugins/actions/server/routes/delete.test.ts b/x-pack/plugins/actions/server/routes/delete.test.ts index 160092eb8c101..b250e607738e6 100644 --- a/x-pack/plugins/actions/server/routes/delete.test.ts +++ b/x-pack/plugins/actions/server/routes/delete.test.ts @@ -104,7 +104,7 @@ describe('deleteActionRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/execute.test.ts b/x-pack/plugins/actions/server/routes/execute.test.ts index 3bcd2cf60811d..39319ff1dabf2 100644 --- a/x-pack/plugins/actions/server/routes/execute.test.ts +++ b/x-pack/plugins/actions/server/routes/execute.test.ts @@ -167,7 +167,7 @@ describe('executeActionRoute', () => { const [, handler] = router.post.mock.calls[0]; - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/get_oauth_access_token.test.ts b/x-pack/plugins/actions/server/routes/get_oauth_access_token.test.ts index ae06068273ca3..c1b7dd26aff15 100644 --- a/x-pack/plugins/actions/server/routes/get_oauth_access_token.test.ts +++ b/x-pack/plugins/actions/server/routes/get_oauth_access_token.test.ts @@ -216,7 +216,7 @@ describe('getOAuthAccessToken', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/create.test.ts b/x-pack/plugins/actions/server/routes/legacy/create.test.ts index e711f73265f53..05993e44746f9 100644 --- a/x-pack/plugins/actions/server/routes/legacy/create.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/create.test.ts @@ -141,7 +141,7 @@ describe('createActionRoute', () => { const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); }); it('should track every call', async () => { diff --git a/x-pack/plugins/actions/server/routes/legacy/delete.test.ts b/x-pack/plugins/actions/server/routes/legacy/delete.test.ts index e16614a57fd04..2bfb5c7810e46 100644 --- a/x-pack/plugins/actions/server/routes/legacy/delete.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/delete.test.ts @@ -112,7 +112,7 @@ describe('deleteActionRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/execute.test.ts b/x-pack/plugins/actions/server/routes/legacy/execute.test.ts index 53e7d038dfea5..c989731407650 100644 --- a/x-pack/plugins/actions/server/routes/legacy/execute.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/execute.test.ts @@ -170,7 +170,7 @@ describe('executeActionRoute', () => { const [, handler] = router.post.mock.calls[0]; - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/get.test.ts b/x-pack/plugins/actions/server/routes/legacy/get.test.ts index 6a19400da0fb5..732c964fb8284 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get.test.ts @@ -146,7 +146,7 @@ describe('getActionRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/get_all.test.ts b/x-pack/plugins/actions/server/routes/legacy/get_all.test.ts index e999c769f3dbb..e8657e56259e1 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get_all.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get_all.test.ts @@ -97,7 +97,7 @@ describe('getAllActionRoute', () => { const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts b/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts index 4674bbb9936a6..ec57c4b9a99a9 100644 --- a/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts @@ -159,7 +159,7 @@ describe('listActionTypesRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/legacy/update.test.ts b/x-pack/plugins/actions/server/routes/legacy/update.test.ts index 304b504636c91..493d1c873690e 100644 --- a/x-pack/plugins/actions/server/routes/legacy/update.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/update.test.ts @@ -172,7 +172,7 @@ describe('updateActionRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/actions/server/routes/update.test.ts b/x-pack/plugins/actions/server/routes/update.test.ts index aef179264ac48..9fdac7740129d 100644 --- a/x-pack/plugins/actions/server/routes/update.test.ts +++ b/x-pack/plugins/actions/server/routes/update.test.ts @@ -174,7 +174,7 @@ describe('updateActionRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyAccessAndContext).toHaveBeenCalledWith(licenseState, expect.any(Function)); }); diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts index 85e06f0422431..1496974581e89 100644 --- a/x-pack/plugins/actions/server/usage/task.ts +++ b/x-pack/plugins/actions/server/usage/task.ts @@ -32,7 +32,9 @@ export function initializeActionsTelemetry( } export function scheduleActionsTelemetry(logger: Logger, taskManager: TaskManagerStartContract) { - scheduleTasks(logger, taskManager); + scheduleTasks(logger, taskManager).catch(() => { + // it shouldn't throw anything. But adding the catch just in case + }); } function registerActionsTelemetryTask( diff --git a/x-pack/plugins/aiops/server/plugin.ts b/x-pack/plugins/aiops/server/plugin.ts index 81ad429c387e0..7e99a89dab5b5 100755 --- a/x-pack/plugins/aiops/server/plugin.ts +++ b/x-pack/plugins/aiops/server/plugin.ts @@ -62,7 +62,7 @@ export class AiopsPlugin const router = core.http.createRouter(); // Register server side APIs - core.getStartServices().then(([coreStart, depsStart]) => { + void core.getStartServices().then(([coreStart, depsStart]) => { defineLogRateAnalysisRoute(router, aiopsLicense, this.logger, coreStart, this.usageCounter); defineCategorizationFieldValidationRoute(router, aiopsLicense, this.usageCounter); }); diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/grouping_handler.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/grouping_handler.ts index 5266858e6d3bc..3c7a1f4ff5478 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/grouping_handler.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/grouping_handler.ts @@ -221,7 +221,7 @@ export const groupingHandlerFactory = } }, MAX_CONCURRENT_QUERIES); - groupHistogramQueue.push(significantItemGroups); + await groupHistogramQueue.push(significantItemGroups); await groupHistogramQueue.drain(); } } catch (e) { diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts index 1a61edde6864b..8fd134df69cac 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts @@ -156,7 +156,7 @@ export const histogramHandlerFactory = } }, MAX_CONCURRENT_QUERIES); - fieldValueHistogramQueue.push(significantTerms); + await fieldValueHistogramQueue.push(significantTerms); await fieldValueHistogramQueue.drain(); } diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/route_handler_factory.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/route_handler_factory.ts index 69b9cc923799d..0864efbcf63da 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/route_handler_factory.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/route_handler_factory.ts @@ -133,7 +133,7 @@ export function routeHandlerFactory( } // Do not call this using `await` so it will run asynchronously while we return the stream already. - runAnalysis(); + void runAnalysis(); return response.ok(responseWithHeaders); }); diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/install_with_timeout.ts b/x-pack/plugins/alerting/server/alerts_service/lib/install_with_timeout.ts index 759aeba71cd41..e93dcf2e09f34 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/install_with_timeout.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/install_with_timeout.ts @@ -48,10 +48,12 @@ export const installWithTimeout = async ({ reject(new Error(msg)); }, timeoutMs); - firstValueFrom(pluginStop$).then(() => { - clearTimeout(timeoutId); - reject(new InstallShutdownError()); - }); + firstValueFrom(pluginStop$) + .then(() => { + clearTimeout(timeoutId); + reject(new InstallShutdownError()); + }) + .catch(() => reject(new InstallShutdownError())); }); }; diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.test.ts b/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.test.ts index 89ab626bed462..4a2ac84515fe9 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.test.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.test.ts @@ -121,7 +121,7 @@ describe('deleteBackfill()', () => { let rulesClient: RulesClient; beforeEach(async () => { - jest.resetAllMocks(); + jest.clearAllMocks(); rulesClient = new RulesClient(rulesClientParams); unsecuredSavedObjectsClient.get.mockResolvedValue(mockAdHocRunSO); unsecuredSavedObjectsClient.delete.mockResolvedValue({}); diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.ts b/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.ts index fe43e3555e8d3..3851efc1c2ebd 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/delete/delete_backfill.ts @@ -85,7 +85,7 @@ async function deleteWithOCC(context: RulesClientContext, { id }: { id: string } ); // remove the associated task - context.taskManager.removeIfExists(id); + context.taskManager.removeIfExists(id).catch(() => {}); return removeResult; } catch (err) { diff --git a/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts index a2f1c0dfa92f1..9ace9c2d8f491 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts @@ -3062,7 +3062,7 @@ describe('create()', () => { rulesClientParams.createAPIKey.mockImplementation(() => { throw new Error('no'); }); - expect( + await expect( async () => await rulesClient.create({ data }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Error creating rule: could not create API key - no"` diff --git a/x-pack/plugins/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/update/update_rule.test.ts index d9bc9c8816845..748b41c0d2f1a 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -1618,7 +1618,7 @@ describe('update()', () => { rulesClientParams.createAPIKey.mockImplementation(() => { throw new Error('no'); }); - expect( + await expect( async () => await rulesClient.update({ id: '1', diff --git a/x-pack/plugins/alerting/server/invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation.ts b/x-pack/plugins/alerting/server/invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation.ts index 6711dd3fd6d24..bde9cd8aa2131 100644 --- a/x-pack/plugins/alerting/server/invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation.ts +++ b/x-pack/plugins/alerting/server/invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation.ts @@ -14,7 +14,7 @@ export const bulkMarkApiKeysForInvalidation = async ( logger: Logger, savedObjectsClient: SavedObjectsClientContract ): Promise => { - withSpan({ name: 'bulkMarkApiKeysForInvalidation', type: 'rules' }, async () => { + await withSpan({ name: 'bulkMarkApiKeysForInvalidation', type: 'rules' }, async () => { if (apiKeys.length === 0) { return; } diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 907c85ab27da5..f0006e6974e33 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -617,12 +617,16 @@ export class AlertingPlugin { : Promise.resolve([]); }); - this.eventLogService!.isEsContextReady().then(() => { - scheduleAlertingTelemetry(this.telemetryLogger, plugins.taskManager); - }); - - scheduleAlertingHealthCheck(this.logger, this.config, plugins.taskManager); - scheduleApiKeyInvalidatorTask(this.telemetryLogger, this.config, plugins.taskManager); + this.eventLogService!.isEsContextReady() + .then(() => { + scheduleAlertingTelemetry(this.telemetryLogger, plugins.taskManager); + }) + .catch(() => {}); // it shouldn't reject, but just in case + + scheduleAlertingHealthCheck(this.logger, this.config, plugins.taskManager).catch(() => {}); // it shouldn't reject, but just in case + scheduleApiKeyInvalidatorTask(this.telemetryLogger, this.config, plugins.taskManager).catch( + () => {} + ); // it shouldn't reject, but just in case return { listTypes: ruleTypeRegistry!.list.bind(this.ruleTypeRegistry!), diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.test.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.test.ts index 55a8ea2ae22ea..5ba4b736fa81e 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.test.ts @@ -65,6 +65,6 @@ describe('deleteBackfillRoute', () => { }); const [, handler] = router.delete.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: 'abc' } }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.test.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.test.ts index fb461fa416f9b..a8a0a210c8817 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.test.ts @@ -140,6 +140,6 @@ describe('findBackfillRoute', () => { }); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { body: mockFindOptions }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.test.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.test.ts index f24018b1c8deb..79ac8df1ed4b5 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.test.ts @@ -99,6 +99,6 @@ describe('getBackfillRoute', () => { const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: 'abc' } }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.test.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.test.ts index 30545a3ac1617..c08cca6dfe683 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.test.ts @@ -148,6 +148,6 @@ describe('scheduleBackfillRoute', () => { { rulesClient }, { body: mockScheduleOptions } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/delete_rule.test.ts b/x-pack/plugins/alerting/server/routes/delete_rule.test.ts index b64dff27c5b90..71222d859d3c8 100644 --- a/x-pack/plugins/alerting/server/routes/delete_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/delete_rule.test.ts @@ -102,7 +102,7 @@ describe('deleteRuleRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/get_action_error_log.test.ts b/x-pack/plugins/alerting/server/routes/get_action_error_log.test.ts index 408ed049044c6..f95fe38a5ee64 100644 --- a/x-pack/plugins/alerting/server/routes/get_action_error_log.test.ts +++ b/x-pack/plugins/alerting/server/routes/get_action_error_log.test.ts @@ -115,7 +115,7 @@ describe('getActionErrorLogRoute', () => { ['notFound'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( `[Error: Saved object [alert/1] not found]` ); }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.test.ts b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.test.ts index 5eca11c27a4b2..319de59a01bfd 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.test.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.test.ts @@ -114,7 +114,7 @@ describe('getRuleAlertSummaryRoute', () => { ['notFound'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( `[Error: Saved object [alert/1] not found]` ); }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.test.ts b/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.test.ts index e92b54769d329..af64b80851695 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.test.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.test.ts @@ -99,7 +99,7 @@ describe('getRuleExecutionKPIRoute', () => { ['notFound'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( `[Error: Saved object [alert/1] not found]` ); }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.test.ts b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.test.ts index a0dd57da558eb..3b1f950fb45c6 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.test.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.test.ts @@ -145,7 +145,7 @@ describe('getRuleExecutionLogRoute', () => { ['notFound'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot( `[Error: Saved object [alert/1] not found]` ); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.test.ts b/x-pack/plugins/alerting/server/routes/legacy/create.test.ts index e090cac73a932..d50d7fcb79e38 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.test.ts @@ -432,7 +432,7 @@ describe('createAlertRoute', () => { const [context, req, res] = mockHandlerArguments({ rulesClient }, {}); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts b/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts index fee6b3db736fe..9a3ccdf84c82c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts @@ -108,7 +108,7 @@ describe('deleteAlertRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/find.test.ts b/x-pack/plugins/alerting/server/routes/legacy/find.test.ts index 60ca90865be1d..013fa119dbdf1 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/find.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/find.test.ts @@ -149,7 +149,7 @@ describe('findAlertRoute', () => { }, ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get.test.ts b/x-pack/plugins/alerting/server/routes/legacy/get.test.ts index 7d1a6ac656896..e97996837f1d7 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get.test.ts @@ -151,7 +151,7 @@ describe('getAlertRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts index c680007f197e1..b9abeafd00ecc 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts @@ -219,7 +219,7 @@ describe('listAlertTypesRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts index 9e23470215d36..44a4cf629813a 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts @@ -225,7 +225,7 @@ describe('updateAlertRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts index 040ba6e8ea9ab..dfd5073ae1026 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts @@ -112,7 +112,7 @@ describe('archiveMaintenanceWindowRoute', () => { }, } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -127,6 +127,6 @@ describe('archiveMaintenanceWindowRoute', () => { const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts index c39fe061b69e5..eaab39665fb6b 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts @@ -110,7 +110,7 @@ describe('bulkGetMaintenanceWindowRoute', () => { { maintenanceWindowClient }, { body: { ids: ['test-id-1', 'test-id-2', 'test-id-3'] } } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -124,6 +124,6 @@ describe('bulkGetMaintenanceWindowRoute', () => { }); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts index 5437533ba8342..9cac558652d76 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts @@ -101,7 +101,7 @@ describe('createMaintenanceWindowRoute', () => { { maintenanceWindowClient }, { body: createParams } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -116,6 +116,6 @@ describe('createMaintenanceWindowRoute', () => { const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts index 7ac0db328cf9d..b248fe1394318 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts @@ -85,7 +85,7 @@ describe('deleteMaintenanceWindowRoute', () => { { maintenanceWindowClient }, { params: { id: 'test-id' } } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -100,6 +100,6 @@ describe('deleteMaintenanceWindowRoute', () => { const [, handler] = router.delete.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts index a9a7d22e20751..21d821d2e0db3 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts @@ -93,7 +93,7 @@ describe('findMaintenanceWindowsRoute', () => { }); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -107,6 +107,6 @@ describe('findMaintenanceWindowsRoute', () => { }); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts index e7ec470839fe9..4141d114c98d8 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts @@ -88,7 +88,7 @@ describe('finishMaintenanceWindowRoute', () => { { maintenanceWindowClient }, { params: { id: 'test-id' } } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -102,6 +102,6 @@ describe('finishMaintenanceWindowRoute', () => { }); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts index 9e17aed88eaf0..487878fdb0e9a 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts @@ -88,7 +88,7 @@ describe('getMaintenanceWindowRoute', () => { { maintenanceWindowClient }, { params: { id: 'test-id' } } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -102,6 +102,6 @@ describe('getMaintenanceWindowRoute', () => { }); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts index c9f9fa2841374..4121aeb1d7f11 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts @@ -92,7 +92,7 @@ describe('getActiveMaintenanceWindowsRoute', () => { }); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts index d7425b150d1ea..a4bc9701f99a1 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts @@ -115,7 +115,7 @@ describe('updateMaintenanceWindowRoute', () => { body: updateParams, } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); test('ensures only platinum license can access API', async () => { @@ -129,6 +129,6 @@ describe('updateMaintenanceWindowRoute', () => { }); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ maintenanceWindowClient }, { body: {} }); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts index 51a7da620dfb3..77221de2d714b 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts @@ -316,7 +316,7 @@ describe('aggregateRulesRoute', () => { }, ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.test.ts index 3f2a31ac6cc96..90a13ba09a4cf 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.test.ts @@ -100,7 +100,7 @@ describe('bulkDeleteRulesRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); it('ensures the rule type gets validated for the license', async () => { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.test.ts index cd71a78a5f51c..0dc0793118c23 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.test.ts @@ -101,7 +101,7 @@ describe('bulkDisableRulesRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); it('ensures the rule type gets validated for the license', async () => { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts index 82480acf779f9..295299db3a117 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts @@ -169,7 +169,7 @@ describe('bulkEditRulesRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); it('ensures the rule type gets validated for the license', async () => { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts index 9a0d22dadc9a4..272d91997a9f5 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.test.ts @@ -103,7 +103,7 @@ describe('bulkEnableRulesRoute', () => { } ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); }); it('ensures the rule type gets validated for the license', async () => { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.test.ts index 4ae904261eb24..13c6a69087635 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.test.ts @@ -198,7 +198,7 @@ describe('cloneRuleRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts index 8f488dafd2fa5..ba6c3c25a1c43 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts @@ -632,7 +632,7 @@ describe('createRuleRoute', () => { const [context, req, res] = mockHandlerArguments({ rulesClient }, {}); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts index 53c339a66b864..4e3c9b635ec3a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts @@ -360,7 +360,7 @@ describe('findRulesRoute', () => { }, ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts index f854109f16f1b..a9ae97e521ef5 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.test.ts @@ -188,7 +188,7 @@ describe('getRuleRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts index bd6c8e144e91c..7b7d871007060 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts @@ -197,7 +197,7 @@ describe('resolveRuleRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.test.ts index a8a1992480841..02b9fd4e32a5f 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.test.ts @@ -118,7 +118,7 @@ describe('getRuleTagsRoute', () => { }, ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.test.ts index c04c1aa345d1a..e1ed7b52ae710 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.test.ts @@ -273,7 +273,7 @@ describe('updateRuleRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/routes/rule_types.test.ts b/x-pack/plugins/alerting/server/routes/rule_types.test.ts index f14c3472dcc93..a6483f15f9f1c 100644 --- a/x-pack/plugins/alerting/server/routes/rule_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule_types.test.ts @@ -250,7 +250,7 @@ describe('ruleTypesRoute', () => { ['ok'] ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + await expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); }); diff --git a/x-pack/plugins/alerting/server/rules_client/lib/add_generated_action_values.test.ts b/x-pack/plugins/alerting/server/rules_client/lib/add_generated_action_values.test.ts index 5a969e7e8c836..ac58ab1a12685 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/add_generated_action_values.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/add_generated_action_values.test.ts @@ -148,7 +148,7 @@ describe('addGeneratedActionValues()', () => { }); test('throws error if KQL is not valid', async () => { - expect(async () => + await expect(async () => addGeneratedActionValues( [ { diff --git a/x-pack/plugins/alerting/server/rules_client/tests/get_action_error_log.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/get_action_error_log.test.ts index 8df9883247683..532511fb313f5 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/get_action_error_log.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/get_action_error_log.test.ts @@ -507,9 +507,9 @@ describe('getActionErrorLog()', () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getRuleSavedObject()); eventLogClient.findEventsBySavedObjectIds.mockRejectedValueOnce(new Error('OMG 3!')); - expect(rulesClient.getActionErrorLog(getActionErrorLogParams())).rejects.toMatchInlineSnapshot( - `[Error: OMG 3!]` - ); + await expect( + rulesClient.getActionErrorLog(getActionErrorLogParams()) + ).rejects.toMatchInlineSnapshot(`[Error: OMG 3!]`); }); describe('authorization', () => { beforeEach(() => { diff --git a/x-pack/plugins/alerting/server/rules_client/tests/get_alert_summary.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/get_alert_summary.test.ts index b5815b6022cb9..77e3d19a37540 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/get_alert_summary.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/get_alert_summary.test.ts @@ -372,7 +372,7 @@ describe('getAlertSummary()', () => { eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(AlertSummaryFindEventsResult); const dateStart = 'ain"t no way this will get parsed as a date'; - expect(rulesClient.getAlertSummary({ id: '1', dateStart })).rejects.toMatchInlineSnapshot( + await expect(rulesClient.getAlertSummary({ id: '1', dateStart })).rejects.toMatchInlineSnapshot( `[Error: Invalid date for parameter dateStart: "ain"t no way this will get parsed as a date"]` ); }); @@ -381,7 +381,9 @@ describe('getAlertSummary()', () => { unsecuredSavedObjectsClient.get.mockRejectedValueOnce(new Error('OMG!')); eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(AlertSummaryFindEventsResult); - expect(rulesClient.getAlertSummary({ id: '1' })).rejects.toMatchInlineSnapshot(`[Error: OMG!]`); + await expect(rulesClient.getAlertSummary({ id: '1' })).rejects.toMatchInlineSnapshot( + `[Error: OMG!]` + ); }); test('findEvents throws an error', async () => { diff --git a/x-pack/plugins/alerting/server/rules_client/tests/get_execution_log.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/get_execution_log.test.ts index 6bc7076ab3329..f8416e9cdb6b6 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/get_execution_log.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/get_execution_log.test.ts @@ -553,7 +553,7 @@ describe('getExecutionLogForRule()', () => { eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); const dateStart = 'ain"t no way this will get parsed as a date'; - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams({ dateStart })) ).rejects.toMatchInlineSnapshot( `[Error: Invalid date for parameter dateStart: "ain"t no way this will get parsed as a date"]` @@ -565,7 +565,7 @@ describe('getExecutionLogForRule()', () => { eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); const dateEnd = 'ain"t no way this will get parsed as a date'; - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams({ dateEnd })) ).rejects.toMatchInlineSnapshot( `[Error: Invalid date for parameter dateEnd: "ain"t no way this will get parsed as a date"]` @@ -576,7 +576,7 @@ describe('getExecutionLogForRule()', () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getRuleSavedObject()); eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams({ page: -3 })) ).rejects.toMatchInlineSnapshot(`[Error: Invalid page field "-3" - must be greater than 0]`); }); @@ -585,7 +585,7 @@ describe('getExecutionLogForRule()', () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getRuleSavedObject()); eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams({ perPage: -3 })) ).rejects.toMatchInlineSnapshot(`[Error: Invalid perPage field "-3" - must be greater than 0]`); }); @@ -594,7 +594,7 @@ describe('getExecutionLogForRule()', () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getRuleSavedObject()); eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); - expect( + await expect( rulesClient.getExecutionLogForRule( getExecutionLogByIdParams({ sort: [{ foo: { order: 'desc' } }] }) ) @@ -607,7 +607,7 @@ describe('getExecutionLogForRule()', () => { unsecuredSavedObjectsClient.get.mockRejectedValueOnce(new Error('OMG!')); eventLogClient.aggregateEventsBySavedObjectIds.mockResolvedValueOnce(aggregateResults); - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams()) ).rejects.toMatchInlineSnapshot(`[Error: OMG!]`); }); @@ -616,7 +616,7 @@ describe('getExecutionLogForRule()', () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getRuleSavedObject()); eventLogClient.aggregateEventsBySavedObjectIds.mockRejectedValueOnce(new Error('OMG 2!')); - expect( + await expect( rulesClient.getExecutionLogForRule(getExecutionLogByIdParams()) ).rejects.toMatchInlineSnapshot(`[Error: OMG 2!]`); }); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update_api_key.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update_api_key.test.ts index 0f72a1e20d1d5..dbf80eb978d2f 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update_api_key.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update_api_key.test.ts @@ -287,7 +287,7 @@ describe('updateApiKey()', () => { rulesClientParams.createAPIKey.mockImplementation(() => { throw new Error('no'); }); - expect( + await expect( async () => await rulesClient.updateApiKey({ id: '1' }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Error updating API key for rule: could not create API key - no"` diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 627f88bab4e69..713ee52015239 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -551,7 +551,7 @@ export class TaskRunner< // Most likely a 409 conflict error, which is ok, we'll try again at the next rule run this.logger.debug(`Failed to clear expired snoozes: ${e.message}`); } - })(); + })().catch(() => {}); return runRuleParams; }); diff --git a/x-pack/plugins/alerting/server/usage/task.ts b/x-pack/plugins/alerting/server/usage/task.ts index 507970d436d6f..0cc08db911226 100644 --- a/x-pack/plugins/alerting/server/usage/task.ts +++ b/x-pack/plugins/alerting/server/usage/task.ts @@ -38,7 +38,7 @@ export function initializeAlertingTelemetry( export function scheduleAlertingTelemetry(logger: Logger, taskManager?: TaskManagerStartContract) { if (taskManager) { - scheduleTasks(logger, taskManager); + scheduleTasks(logger, taskManager).catch(() => {}); // it shouldn't reject, but just in case } } diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts index 9dd6dc1bdd64f..16e39eb46ee34 100644 --- a/x-pack/plugins/canvas/server/plugin.ts +++ b/x-pack/plugins/canvas/server/plugin.ts @@ -99,7 +99,7 @@ export class CanvasPlugin implements Plugin { public start(coreStart: CoreStart) { const client = coreStart.savedObjects.createInternalRepository(); - initializeTemplates(client); + initializeTemplates(client).catch(() => {}); } public stop() {} diff --git a/x-pack/plugins/canvas/server/routes/shareables/zip.ts b/x-pack/plugins/canvas/server/routes/shareables/zip.ts index 7f5a414c5dba0..d476edb8ca4ac 100644 --- a/x-pack/plugins/canvas/server/routes/shareables/zip.ts +++ b/x-pack/plugins/canvas/server/routes/shareables/zip.ts @@ -33,7 +33,7 @@ export function initializeZipShareableWorkpadRoute(deps: RouteInitializerDeps) { archive.file(SHAREABLE_RUNTIME_FILE, { name: `${SHAREABLE_RUNTIME_NAME}.js` }); const result = { headers: { 'content-type': 'application/zip' }, body: archive }; - archive.finalize(); + await archive.finalize(); return response.ok(result); } diff --git a/x-pack/plugins/cases/server/authorization/authorization.ts b/x-pack/plugins/cases/server/authorization/authorization.ts index e3dc970b38182..c67b69c4f305f 100644 --- a/x-pack/plugins/cases/server/authorization/authorization.ts +++ b/x-pack/plugins/cases/server/authorization/authorization.ts @@ -171,7 +171,7 @@ export class Authorization { return { authorized, unauthorized }; } - private async logSavedObjects({ + private logSavedObjects({ entities, operation, error, diff --git a/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts index df40e3841f1d7..d126237dd8aac 100644 --- a/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts +++ b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts @@ -39,8 +39,8 @@ describe('PersistableStateAndExternalReferencesLimiter', () => { }); describe('countOfItemsWithinCase', () => { - it('calls the attachment service with the right params', () => { - limiter.countOfItemsWithinCase(caseId); + it('calls the attachment service with the right params', async () => { + await limiter.countOfItemsWithinCase(caseId); expect( attachmentService.countPersistableStateAndExternalReferenceAttachments diff --git a/x-pack/plugins/cases/server/telemetry/index.ts b/x-pack/plugins/cases/server/telemetry/index.ts index af1e9125a8a55..5f10dcc6a3c72 100644 --- a/x-pack/plugins/cases/server/telemetry/index.ts +++ b/x-pack/plugins/cases/server/telemetry/index.ts @@ -36,7 +36,7 @@ interface CreateCasesTelemetryArgs { kibanaVersion: PluginInitializerContext['env']['packageInfo']['version']; } -export const createCasesTelemetry = async ({ +export const createCasesTelemetry = ({ core, taskManager, usageCollection, diff --git a/x-pack/plugins/cloud_defend/server/lib/fleet_util.ts b/x-pack/plugins/cloud_defend/server/lib/fleet_util.ts index 0e51a343e3770..c0db69a5dc128 100644 --- a/x-pack/plugins/cloud_defend/server/lib/fleet_util.ts +++ b/x-pack/plugins/cloud_defend/server/lib/fleet_util.ts @@ -89,9 +89,15 @@ async function addDataViewToAllSpaces(savedObjectsClient: SavedObjectsClientCont perPage: 100, }); - cloudDefendDataViews.saved_objects.forEach((dataView) => { - savedObjectsClient.updateObjectsSpaces([{ id: dataView.id, type: 'index-pattern' }], ['*'], []); - }); + await Promise.all( + cloudDefendDataViews.saved_objects.map((dataView) => + savedObjectsClient.updateObjectsSpaces( + [{ id: dataView.id, type: 'index-pattern' }], + ['*'], + [] + ) + ) + ); } export const getCloudDefendAgentPolicies = async ( diff --git a/x-pack/plugins/cloud_defend/server/plugin.ts b/x-pack/plugins/cloud_defend/server/plugin.ts index c8a6bc5083b1c..b7c5016776816 100644 --- a/x-pack/plugins/cloud_defend/server/plugin.ts +++ b/x-pack/plugins/cloud_defend/server/plugin.ts @@ -55,23 +55,26 @@ export class CloudDefendPlugin implements Plugin { - plugins.fleet.registerExternalCallback( - 'packagePolicyCreate', - async (packagePolicy: NewPackagePolicy): Promise => { - const license = await plugins.licensing.refresh(); - if (isCloudDefendPackage(packagePolicy.package?.name)) { - if (!isSubscriptionAllowed(this.isCloudEnabled, license)) { - throw new Error( - 'To use this feature you must upgrade your subscription or start a trial' - ); + plugins.fleet + .fleetSetupCompleted() + .then(async () => { + plugins.fleet.registerExternalCallback( + 'packagePolicyCreate', + async (packagePolicy: NewPackagePolicy): Promise => { + const license = await plugins.licensing.refresh(); + if (isCloudDefendPackage(packagePolicy.package?.name)) { + if (!isSubscriptionAllowed(this.isCloudEnabled, license)) { + throw new Error( + 'To use this feature you must upgrade your subscription or start a trial' + ); + } } - } - return packagePolicy; - } - ); - }); + return packagePolicy; + } + ); + }) + .catch(() => {}); // it shouldn't reject, but just in case plugins.fleet.registerExternalCallback( 'packagePolicyPostCreate', diff --git a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts index 0e9cf02ad0663..a3d166cf69688 100644 --- a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts @@ -29,9 +29,15 @@ async function addDataViewToAllSpaces(savedObjectsClient: SavedObjectsClientCont perPage: 100, }); - cspmDataViews.saved_objects.forEach((dataView) => { - savedObjectsClient.updateObjectsSpaces([{ id: dataView.id, type: 'index-pattern' }], ['*'], []); - }); + await Promise.all( + cspmDataViews.saved_objects.map((dataView) => + savedObjectsClient.updateObjectsSpaces( + [{ id: dataView.id, type: 'index-pattern' }], + ['*'], + [] + ) + ) + ); } export const isCspPackagePolicyInstalled = async ( diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index 58a143b220857..561d1bcaa7efd 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -100,102 +100,104 @@ export class CspPlugin } public start(core: CoreStart, plugins: CspServerPluginStartDeps): CspServerPluginStart { - plugins.fleet.fleetSetupCompleted().then(async () => { - const packageInfo = await plugins.fleet.packageService.asInternalUser.getInstallation( - CLOUD_SECURITY_POSTURE_PACKAGE_NAME - ); - - // If package is installed we want to make sure all needed assets are installed - if (packageInfo) { - // noinspection ES6MissingAwait - this.initialize(core, plugins.taskManager); - } - - plugins.fleet.registerExternalCallback( - 'packagePolicyCreate', - async (packagePolicy: NewPackagePolicy): Promise => { - const license = await plugins.licensing.refresh(); - if (isCspPackage(packagePolicy.package?.name)) { - if (!isSubscriptionAllowed(this.isCloudEnabled, license)) { - throw new Error( - 'To use this feature you must upgrade your subscription or start a trial' - ); - } + plugins.fleet + .fleetSetupCompleted() + .then(async () => { + const packageInfo = await plugins.fleet.packageService.asInternalUser.getInstallation( + CLOUD_SECURITY_POSTURE_PACKAGE_NAME + ); + + // If package is installed we want to make sure all needed assets are installed + if (packageInfo) { + this.initialize(core, plugins.taskManager).catch(() => {}); + } - if (!isSingleEnabledInput(packagePolicy.inputs)) { - throw new Error('Only one enabled input is allowed per policy'); + plugins.fleet.registerExternalCallback( + 'packagePolicyCreate', + async (packagePolicy: NewPackagePolicy): Promise => { + const license = await plugins.licensing.refresh(); + if (isCspPackage(packagePolicy.package?.name)) { + if (!isSubscriptionAllowed(this.isCloudEnabled, license)) { + throw new Error( + 'To use this feature you must upgrade your subscription or start a trial' + ); + } + + if (!isSingleEnabledInput(packagePolicy.inputs)) { + throw new Error('Only one enabled input is allowed per policy'); + } } - } - return packagePolicy; - } - ); - - plugins.fleet.registerExternalCallback( - 'packagePolicyCreate', - async ( - packagePolicy: NewPackagePolicy, - soClient: SavedObjectsClientContract - ): Promise => { - if (isCspPackage(packagePolicy.package?.name)) { - return cleanupCredentials(packagePolicy); + return packagePolicy; } + ); + + plugins.fleet.registerExternalCallback( + 'packagePolicyCreate', + async ( + packagePolicy: NewPackagePolicy, + soClient: SavedObjectsClientContract + ): Promise => { + if (isCspPackage(packagePolicy.package?.name)) { + return cleanupCredentials(packagePolicy); + } - return packagePolicy; - } - ); - - plugins.fleet.registerExternalCallback( - 'packagePolicyUpdate', - async ( - packagePolicy: UpdatePackagePolicy, - soClient: SavedObjectsClientContract - ): Promise => { - if (isCspPackage(packagePolicy.package?.name)) { - return cleanupCredentials(packagePolicy); + return packagePolicy; } - - return packagePolicy; - } - ); - - plugins.fleet.registerExternalCallback( - 'packagePolicyPostCreate', - async ( - packagePolicy: PackagePolicy, - soClient: SavedObjectsClientContract - ): Promise => { - if (isCspPackage(packagePolicy.package?.name)) { - await this.initialize(core, plugins.taskManager); - await onPackagePolicyPostCreateCallback(this.logger, packagePolicy, soClient); + ); + + plugins.fleet.registerExternalCallback( + 'packagePolicyUpdate', + async ( + packagePolicy: UpdatePackagePolicy, + soClient: SavedObjectsClientContract + ): Promise => { + if (isCspPackage(packagePolicy.package?.name)) { + return cleanupCredentials(packagePolicy); + } return packagePolicy; } + ); + + plugins.fleet.registerExternalCallback( + 'packagePolicyPostCreate', + async ( + packagePolicy: PackagePolicy, + soClient: SavedObjectsClientContract + ): Promise => { + if (isCspPackage(packagePolicy.package?.name)) { + await this.initialize(core, plugins.taskManager); + await onPackagePolicyPostCreateCallback(this.logger, packagePolicy, soClient); + + return packagePolicy; + } - return packagePolicy; - } - ); - - plugins.fleet.registerExternalCallback( - 'packagePolicyPostDelete', - async (deletedPackagePolicies: DeepReadonly) => { - for (const deletedPackagePolicy of deletedPackagePolicies) { - if (isCspPackage(deletedPackagePolicy.package?.name)) { - const soClient = core.savedObjects.createInternalRepository(); - const packagePolicyService = plugins.fleet.packagePolicyService; - const isPackageExists = await isCspPackagePolicyInstalled( - packagePolicyService, - soClient, - this.logger - ); - if (!isPackageExists) { - await this.uninstallResources(plugins.taskManager, this.logger); + return packagePolicy; + } + ); + + plugins.fleet.registerExternalCallback( + 'packagePolicyPostDelete', + async (deletedPackagePolicies: DeepReadonly) => { + for (const deletedPackagePolicy of deletedPackagePolicies) { + if (isCspPackage(deletedPackagePolicy.package?.name)) { + const soClient = core.savedObjects.createInternalRepository(); + const packagePolicyService = plugins.fleet.packagePolicyService; + const isPackageExists = await isCspPackagePolicyInstalled( + packagePolicyService, + soClient, + this.logger + ); + if (!isPackageExists) { + await this.uninstallResources(plugins.taskManager, this.logger); + } } } } - } - ); - }); + ); + }) + .catch(() => {}); // it shouldn't reject, but just in case return {}; } diff --git a/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts b/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts index 732017db1090f..7b46e4ef113c3 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts @@ -27,7 +27,7 @@ import { defineGetCspBenchmarkRulesStatesRoute } from './benchmark_rules/get_sta * 1. Registers routes * 2. Registers routes handler context */ -export async function setupRoutes({ +export function setupRoutes({ core, logger, isPluginInitialized, diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 657468b76d615..bf5644a0f8bdd 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -57,7 +57,7 @@ export class CrossClusterReplicationServerPlugin implements Plugin { + void firstValueFrom(this.config$).then((config) => { // remoteClusters.isUiEnabled is driven by the xpack.remote_clusters.ui.enabled setting. // The CCR UI depends upon the Remote Clusters UI (e.g. by cross-linking to it), so if // the Remote Clusters UI is disabled we can't show the CCR UI. diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_data_stream.test.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_data_stream.test.ts index 7504a4b55c1cb..8ae7df34888d5 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_data_stream.test.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_data_stream.test.ts @@ -100,7 +100,7 @@ describe('ResultsDataStream', () => { it('should not install space if install not executed', async () => { const resultsDataStream = new ResultsDataStream({ kibanaVersion: '8.13.0' }); - expect(resultsDataStream.installSpace('space1')).rejects.toThrowError(); + await expect(resultsDataStream.installSpace('space1')).rejects.toThrowError(); }); it('should throw error if main install had error', async () => { @@ -115,7 +115,7 @@ describe('ResultsDataStream', () => { (dataStreamSpacesAdapter.install as jest.Mock).mockRejectedValueOnce(error); await resultsDataStream.install(params); - expect(resultsDataStream.installSpace('space1')).rejects.toThrowError(error); + await expect(resultsDataStream.installSpace('space1')).rejects.toThrowError(error); }); }); }); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts index cb6fe9da7c276..f7b2fa3415147 100755 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts @@ -48,13 +48,15 @@ export class EcsDataQualityDashboardPlugin public setup(core: CoreSetup, plugins: PluginSetupDependencies) { this.logger.debug('ecsDataQualityDashboard: Setup'); - this.resultsDataStream.install({ - esClient: core - .getStartServices() - .then(([{ elasticsearch }]) => elasticsearch.client.asInternalUser), - logger: this.logger, - pluginStop$: this.pluginStop$, - }); + this.resultsDataStream + .install({ + esClient: core + .getStartServices() + .then(([{ elasticsearch }]) => elasticsearch.client.asInternalUser), + logger: this.logger, + pluginStop$: this.pluginStop$, + }) + .catch(() => {}); // it shouldn't reject, but just in case core.http.registerRouteHandlerContext< DataQualityDashboardRequestHandlerContext, diff --git a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts index eeb3c6cc4289d..9cc3efb03e195 100644 --- a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts +++ b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts @@ -318,7 +318,7 @@ export class AIAssistantService { if (!anonymizationFieldsIndexName) { await this.anonymizationFieldsDataStream.installSpace(spaceId); - this.createDefaultAnonymizationFields(spaceId); + await this.createDefaultAnonymizationFields(spaceId); } } catch (error) { this.options.logger.error( diff --git a/x-pack/plugins/elastic_assistant/server/lib/executor.test.ts b/x-pack/plugins/elastic_assistant/server/lib/executor.test.ts index 1805df38b789b..bacdd6cac1b49 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/executor.test.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/executor.test.ts @@ -17,14 +17,14 @@ import { KibanaRequest } from '@kbn/core-http-server'; import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server'; import { ExecuteConnectorRequestBody } from '@kbn/elastic-assistant-common'; import { loggerMock } from '@kbn/logging-mocks'; -import { handleStreamStorage } from './parse_stream'; +import * as ParseStream from './parse_stream'; const request = { body: { subAction: 'invokeAI', message: 'hello', }, } as KibanaRequest; -const onLlmResponse = jest.fn(); +const onLlmResponse = jest.fn(async () => {}); // We need it to be a promise, or it'll crash because of missing `.catch` const connectorId = 'testConnectorId'; const mockLogger = loggerMock.create(); const testProps: Omit = { @@ -38,9 +38,8 @@ const testProps: Omit = { onLlmResponse, logger: mockLogger, }; -jest.mock('./parse_stream'); -const mockHandleStreamStorage = handleStreamStorage as jest.Mock; +const handleStreamStorageSpy = jest.spyOn(ParseStream, 'handleStreamStorage'); describe('executeAction', () => { beforeEach(() => { @@ -83,7 +82,7 @@ describe('executeAction', () => { JSON.stringify(readableStream.pipe(new PassThrough())) ); - expect(mockHandleStreamStorage).toHaveBeenCalledWith({ + expect(handleStreamStorageSpy).toHaveBeenCalledWith({ actionTypeId: '.bedrock', onMessageSent: onLlmResponse, logger: mockLogger, diff --git a/x-pack/plugins/elastic_assistant/server/lib/executor.ts b/x-pack/plugins/elastic_assistant/server/lib/executor.ts index b8fa9fe0c5170..e7797805854ec 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/executor.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/executor.ts @@ -92,7 +92,7 @@ export const executeAction = async ({ logger, responseStream: readable, abortSignal, - }); + }).catch(() => {}); return readable.pipe(new PassThrough()); }; diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts index 103c0932f86c3..7664e970b4df8 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts @@ -221,7 +221,7 @@ describe('callAgentExecutor', () => { mockInvokeWithChainCallback({ ...props, agentType }, more), }) ); - const onLlmResponse = jest.fn(); + const onLlmResponse = jest.fn(async () => {}); // We need it to be a promise, or it'll crash because of missing `.catch` await callAgentExecutor({ ...defaultProps, onLlmResponse, isStream: true }); expect(onLlmResponse).toHaveBeenCalledWith( @@ -250,7 +250,7 @@ describe('callAgentExecutor', () => { mockInvokeWithChainCallback({ ...props, agentType }, more), }) ); - const onLlmResponse = jest.fn(); + const onLlmResponse = jest.fn(async () => {}); // We need it to be a promise, or it'll crash because of missing `.catch` await callAgentExecutor({ ...defaultProps, onLlmResponse, isStream: true }); expect(mockPush).toHaveBeenCalledWith({ payload: 'hi', type: 'content' }); diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts index e6863fa5550fe..fdecc1365d43c 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts @@ -162,7 +162,7 @@ export const callAgentExecutor: AgentExecutor = async ({ traceId: streamingSpan?.ids?.['trace.id'], }, isError - ); + ).catch(() => {}); } streamEnd(); didEnd = true; diff --git a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts index 32f5fc47ae770..e579996eb13d1 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts @@ -378,7 +378,7 @@ export const postActionsConnectorExecuteRoute = ( logger.error(err); const error = transformError(err); if (onLlmResponse) { - onLlmResponse(error.message, {}, true); + await onLlmResponse(error.message, {}, true); } telemetry.reportEvent(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { actionTypeId: request.body.actionTypeId, diff --git a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts index 1bc30c41b6b22..9aa0c8ab2f973 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks'; + import type { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin'; import type { EncryptedSavedObjectsClient, @@ -33,8 +35,10 @@ function createEncryptedSavedObjectsStartMock() { function createEncryptedSavedObjectsClientMock(opts?: EncryptedSavedObjectsClientOptions) { return { getDecryptedAsInternalUser: jest.fn(), - createPointInTimeFinderDecryptedAsInternalUser: jest.fn(), - } as jest.Mocked; + createPointInTimeFinderDecryptedAsInternalUser: jest.fn((findOptions, deps) => + savedObjectsClientMock.create().createPointInTimeFinder(findOptions, deps) + ), + } as unknown as jest.Mocked; } export const encryptedSavedObjectsMock = { diff --git a/x-pack/plugins/encrypted_saved_objects/tsconfig.json b/x-pack/plugins/encrypted_saved_objects/tsconfig.json index 7b9087064c109..17dea87aca6ee 100644 --- a/x-pack/plugins/encrypted_saved_objects/tsconfig.json +++ b/x-pack/plugins/encrypted_saved_objects/tsconfig.json @@ -11,6 +11,7 @@ "@kbn/utility-types", "@kbn/core-saved-objects-server", "@kbn/core-saved-objects-base-server-internal", + "@kbn/core-saved-objects-api-server-mocks", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index fb17854f6f674..bae0aacec6ff4 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -259,7 +259,7 @@ describe('callEnterpriseSearchConfigAPI', () => { jest.useFakeTimers({ legacyFakeTimers: true }); // Warning - callEnterpriseSearchConfigAPI(mockDependencies); + void callEnterpriseSearchConfigAPI(mockDependencies); jest.advanceTimersByTime(150); expect(mockDependencies.log.warn).toHaveBeenCalledWith( 'Enterprise Search access check took over 100ms. Please ensure your Enterprise Search server is responding normally and not adversely impacting Kibana load speeds.' diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/create_ml_inference_pipeline.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/create_ml_inference_pipeline.test.ts index 62fc7935b169a..7c3104dc84928 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/create_ml_inference_pipeline.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/create_ml_inference_pipeline.test.ts @@ -78,7 +78,7 @@ describe('createMlInferencePipeline lib function', () => { ); }); - it('should throw an error without creating the pipeline if it already exists', () => { + it('should throw an error without creating the pipeline if it already exists', async () => { mockClient.ingest.getPipeline.mockImplementation(() => Promise.resolve({ [inferencePipelineGeneratedName]: {}, @@ -91,7 +91,7 @@ describe('createMlInferencePipeline lib function', () => { mockClient as unknown as ElasticsearchClient ); - expect(actualResult).rejects.toThrow(Error); + await expect(actualResult).rejects.toThrow(Error); expect(mockClient.ingest.putPipeline).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/get_ml_inference_pipeline_processors.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/get_ml_inference_pipeline_processors.test.ts index 020d717417820..157c9f13ca055 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/get_ml_inference_pipeline_processors.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/pipelines/ml_inference/pipeline_processors/get_ml_inference_pipeline_processors.test.ts @@ -727,8 +727,8 @@ describe('fetchMlInferencePipelineProcessors lib function', () => { }); describe('when Machine Learning is disabled in the current space', () => { - it('should throw an error', () => { - expect(() => + it('should throw an error', async () => { + await expect(() => fetchMlInferencePipelineProcessors( mockClient as unknown as ElasticsearchClient, undefined, diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts index 5e2c472dab7ac..9e017424a8f3d 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts @@ -35,8 +35,8 @@ describe('fetchMlModels', () => { })); }); - it('errors when there is no trained model provider', () => { - expect(() => fetchMlModels(undefined, mockLogger)).rejects.toThrowError( + it('errors when there is no trained model provider', async () => { + await expect(() => fetchMlModels(undefined, mockLogger)).rejects.toThrowError( 'Machine Learning is not enabled' ); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/get_ml_model_deployment_status.test.ts b/x-pack/plugins/enterprise_search/server/lib/ml/get_ml_model_deployment_status.test.ts index 0b0a42630bcc7..9cc66bdb609f9 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/get_ml_model_deployment_status.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/get_ml_model_deployment_status.test.ts @@ -22,8 +22,8 @@ describe('getMlModelDeploymentStatus', () => { jest.clearAllMocks(); }); - it('should error when there is no trained model provider', () => { - expect(() => getMlModelDeploymentStatus('mockModelName', undefined)).rejects.toThrowError( + it('should error when there is no trained model provider', async () => { + await expect(() => getMlModelDeploymentStatus('mockModelName', undefined)).rejects.toThrowError( 'Machine Learning is not enabled' ); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_deployment.test.ts b/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_deployment.test.ts index 67a5c75f0f437..9111bee449ec8 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_deployment.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_deployment.test.ts @@ -26,8 +26,8 @@ describe('startMlModelDeployment', () => { jest.clearAllMocks(); }); - it('should error when there is no trained model provider', () => { - expect(() => startMlModelDeployment(modelName, undefined)).rejects.toThrowError( + it('should error when there is no trained model provider', async () => { + await expect(() => startMlModelDeployment(modelName, undefined)).rejects.toThrowError( 'Machine Learning is not enabled' ); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_download.test.ts b/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_download.test.ts index 80318eab0ce77..51023f643504e 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_download.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/start_ml_model_download.test.ts @@ -26,8 +26,8 @@ describe('startMlModelDownload', () => { jest.clearAllMocks(); }); - it('should error when there is no trained model provider', () => { - expect(() => startMlModelDownload(knownModelName, undefined)).rejects.toThrowError( + it('should error when there is no trained model provider', async () => { + await expect(() => startMlModelDownload(knownModelName, undefined)).rejects.toThrowError( 'Machine Learning is not enabled' ); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/pipelines/ml_inference/get_ml_inference_pipelines.test.ts b/x-pack/plugins/enterprise_search/server/lib/pipelines/ml_inference/get_ml_inference_pipelines.test.ts index 0765fafcc9d1d..89ab6abe8ec77 100644 --- a/x-pack/plugins/enterprise_search/server/lib/pipelines/ml_inference/get_ml_inference_pipelines.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/pipelines/ml_inference/get_ml_inference_pipelines.test.ts @@ -25,8 +25,8 @@ describe('getMlInferencePipelines', () => { jest.clearAllMocks(); }); - it('should throw an error if Machine Learning is disabled in the current space', () => { - expect(() => + it('should throw an error if Machine Learning is disabled in the current space', async () => { + await expect(() => getMlInferencePipelines(mockClient as unknown as ElasticsearchClient, undefined) ).rejects.toThrowError('Machine Learning is not enabled'); }); diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index bd1498e0b0b61..24298c55fdffa 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -274,11 +274,11 @@ export class EnterpriseSearchPlugin implements Plugin { registerStatsRoutes(dependencies); // Analytics Routes (stand-alone product) - getStartServices().then(([coreStart, { data }]) => { + void getStartServices().then(([coreStart, { data }]) => { registerAnalyticsRoutes({ ...dependencies, data, savedObjects: coreStart.savedObjects }); }); - getStartServices().then(([, { security: securityStart }]) => { + void getStartServices().then(([, { security: securityStart }]) => { registerApiKeysRoutes(dependencies, securityStart); }); @@ -292,7 +292,7 @@ export class EnterpriseSearchPlugin implements Plugin { } let savedObjectsStarted: SavedObjectsServiceStart; - getStartServices().then(([coreStart]) => { + void getStartServices().then(([coreStart]) => { savedObjectsStarted = coreStart.savedObjects; if (usageCollection) { diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/adaptive_relevance.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/adaptive_relevance.test.ts index cec2262c95a2e..4df97172fa0d5 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/adaptive_relevance.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/adaptive_relevance.test.ts @@ -27,8 +27,8 @@ describe('search relevance insights routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); @@ -51,8 +51,8 @@ describe('search relevance insights routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, body: { query: 'some query', @@ -80,8 +80,8 @@ describe('search relevance insights routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); @@ -104,8 +104,8 @@ describe('search relevance insights routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, body: { curation: { enabled: true } }, }); @@ -129,8 +129,8 @@ describe('search relevance insights routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine', query: 'foo' }, query: { type: 'curation' }, }); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts index cd1221ec52b80..f86001832a3c6 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts @@ -34,8 +34,8 @@ describe('engine routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute(mockRequest); + it('creates a request handler', async () => { + await mockRouter.callRoute(mockRequest); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/as/engines/collection', @@ -44,7 +44,7 @@ describe('engine routes', () => { }); describe('hasValidData', () => { - it('should correctly validate that the response has data', () => { + it('should correctly validate that the response has data', async () => { mockRequestHandler.createRequest.mockClear(); const response = { meta: { @@ -55,15 +55,15 @@ describe('engine routes', () => { results: [], }; - mockRouter.callRoute(mockRequest); + await mockRouter.callRoute(mockRequest); expect(mockRequestHandler.hasValidData(response)).toBe(true); }); - it('should correctly validate that a response does not have data', () => { + it('should correctly validate that a response does not have data', async () => { mockRequestHandler.createRequest.mockClear(); const response = {}; - mockRouter.callRoute(mockRequest); + await mockRouter.callRoute(mockRequest); expect(mockRequestHandler.hasValidData(response)).toBe(false); }); }); @@ -114,8 +114,8 @@ describe('engine routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({ body: { name: 'some-engine', language: 'en' } }); + it('creates a request handler', async () => { + await mockRouter.callRoute({ body: { name: 'some-engine', language: 'en' } }); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/as/engines/collection', }); @@ -192,8 +192,8 @@ describe('engine routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({ + it('creates a request handler', async () => { + await mockRouter.callRoute({ body: { name: 'some-elasticindexed-engine', search_index: { type: 'elasticsearch', index_name: 'search-elastic-index' }, diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/onboarding.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/onboarding.test.ts index 8990a9e1eeab4..bb281983d5382 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/onboarding.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/onboarding.test.ts @@ -26,8 +26,8 @@ describe('engine routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({ body: {} }); + it('creates a request handler', async () => { + await mockRouter.callRoute({ body: {} }); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/as/onboarding/complete', hasJsonResponse: false, diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts index d82eb06fce68e..fcbf10c080b30 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts @@ -35,8 +35,8 @@ describe('result settings routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); @@ -59,8 +59,8 @@ describe('result settings routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, body: { result_settings: resultFields, diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_settings.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_settings.test.ts index 56e60db543c5d..5b6395912766f 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_settings.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_settings.test.ts @@ -73,8 +73,8 @@ describe('search settings routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); @@ -97,8 +97,8 @@ describe('search settings routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, body: searchSettings, }); @@ -122,8 +122,8 @@ describe('search settings routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts index e92dc63952eb5..1cfb52640c09b 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts @@ -27,8 +27,8 @@ describe('reference application routes', () => { }); }); - it('creates a request to enterprise search', () => { - mockRouter.callRoute({ + it('creates a request to enterprise search', async () => { + await mockRouter.callRoute({ params: { engineName: 'some-engine' }, }); diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/oauth.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/oauth.test.ts index ab9d5e20cfe92..af703c1d0ceee 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/oauth.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/oauth.test.ts @@ -31,8 +31,8 @@ describe('oauth routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({}); + it('creates a request handler', async () => { + await mockRouter.callRoute({}); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/oauth/authorize', @@ -76,8 +76,8 @@ describe('oauth routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({}); + it('creates a request handler', async () => { + await mockRouter.callRoute({}); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/oauth/authorize', @@ -117,8 +117,8 @@ describe('oauth routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({}); + it('creates a request handler', async () => { + await mockRouter.callRoute({}); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/oauth/authorize', diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/security.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/security.test.ts index 744f0e689cd82..ebcbba2767be3 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/security.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/security.test.ts @@ -27,8 +27,8 @@ describe('security routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({}); + it('creates a request handler', async () => { + await mockRouter.callRoute({}); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/org/security', @@ -53,8 +53,8 @@ describe('security routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute({}); + it('creates a request handler', async () => { + await mockRouter.callRoute({}); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/org/security/source_restrictions', diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts index ea8caede378de..06b6fce3baee5 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts @@ -556,7 +556,7 @@ describe('sources routes', () => { }); }); - it('creates a request handler', () => { + it('creates a request handler', async () => { const mockRequest = { params: { sourceId: '123', @@ -564,7 +564,7 @@ describe('sources routes', () => { }, }; - mockRouter.callRoute(mockRequest); + await mockRouter.callRoute(mockRequest); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/sources/:sourceId/reindex_job/:jobId', @@ -1343,8 +1343,8 @@ describe('sources routes', () => { }); }); - it('creates a request handler', () => { - mockRouter.callRoute(mockRequest as any); + it('creates a request handler', async () => { + await mockRouter.callRoute(mockRequest as any); expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ path: '/ws/sources/create', diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index d44ae68745245..5abd44061eb4d 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -167,7 +167,7 @@ describe('EventLogStart', () => { total: 0, data: [], }); - expect( + await expect( eventLogClient.findEventsBySavedObjectIds('saved-object-type', ['saved-object-id'], { start: 'not a date string', }) @@ -181,7 +181,7 @@ describe('EventLogStart', () => { total: 0, data: [], }); - expect( + await expect( eventLogClient.findEventsBySavedObjectIds('saved-object-type', ['saved-object-id'], { end: 'not a date string', }) diff --git a/x-pack/plugins/event_log/server/event_logger.test.ts b/x-pack/plugins/event_log/server/event_logger.test.ts index a9295ada0dd85..ccf5b9a39d7d5 100644 --- a/x-pack/plugins/event_log/server/event_logger.test.ts +++ b/x-pack/plugins/event_log/server/event_logger.test.ts @@ -48,7 +48,7 @@ describe('EventLogger', () => { eventLogger.logEvent({}); await waitForLogEvent(systemLogger); - delay(WRITE_LOG_WAIT_MILLIS); // sleep a bit since event logging is async + await delay(WRITE_LOG_WAIT_MILLIS); // sleep a bit since event logging is async expect(esContext.esAdapter.indexDocument).toHaveBeenCalled(); }); @@ -61,7 +61,7 @@ describe('EventLogger', () => { eventLogger.logEvent({}); await waitForLogEvent(systemLogger); - delay(WRITE_LOG_WAIT_MILLIS); // sleep a bit longer since event logging is async + await delay(WRITE_LOG_WAIT_MILLIS); // sleep a bit longer since event logging is async expect(esContext.esAdapter.indexDocument).toHaveBeenCalled(); expect(esContext.esAdapter.indexDocuments).not.toHaveBeenCalled(); }); diff --git a/x-pack/plugins/event_log/server/plugin.ts b/x-pack/plugins/event_log/server/plugin.ts index 4b0dcbece34b4..b5a6a6bcbe37d 100644 --- a/x-pack/plugins/event_log/server/plugin.ts +++ b/x-pack/plugins/event_log/server/plugin.ts @@ -111,11 +111,18 @@ export class Plugin implements CorePlugin { - if (!success) { - this.systemLogger.error(`initialization failed, events will not be indexed`); - } - }); + this.esContext + .waitTillReady() + .then((success) => { + if (!success) { + this.systemLogger.error(`initialization failed, events will not be indexed`); + } + }) + .catch((error) => { + this.systemLogger.error( + `initialization failed with error: ${error}. Events will not be indexed` + ); + }); // will log the event after initialization this.eventLogger.logEvent({ diff --git a/x-pack/plugins/file_upload/server/telemetry/usage_collector.ts b/x-pack/plugins/file_upload/server/telemetry/usage_collector.ts index d3909a904c26f..b774ac5eb7a97 100644 --- a/x-pack/plugins/file_upload/server/telemetry/usage_collector.ts +++ b/x-pack/plugins/file_upload/server/telemetry/usage_collector.ts @@ -18,7 +18,7 @@ export function initFileUploadTelemetry( ) { coreSetup.savedObjects.registerType(telemetryMappingsType); registerUsageCollector(usageCollection); - coreSetup.getStartServices().then(([core]) => { + void coreSetup.getStartServices().then(([core]) => { setInternalRepository(core.savedObjects.createInternalRepository); }); } diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index aad61fd21c9ae..c24f7859b1189 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -613,12 +613,14 @@ export class FleetPlugin uninstallTokenService, }); licenseService.start(plugins.licensing.license$); - this.telemetryEventsSender.start(plugins.telemetry, core); - this.bulkActionsResolver?.start(plugins.taskManager); - this.fleetUsageSender?.start(plugins.taskManager); - this.checkDeletedFilesTask?.start({ taskManager: plugins.taskManager }); - startFleetUsageLogger(plugins.taskManager); - this.fleetMetricsTask?.start(plugins.taskManager, core.elasticsearch.client.asInternalUser); + this.telemetryEventsSender.start(plugins.telemetry, core).catch(() => {}); + this.bulkActionsResolver?.start(plugins.taskManager).catch(() => {}); + this.fleetUsageSender?.start(plugins.taskManager).catch(() => {}); + this.checkDeletedFilesTask?.start({ taskManager: plugins.taskManager }).catch(() => {}); + startFleetUsageLogger(plugins.taskManager).catch(() => {}); + this.fleetMetricsTask + ?.start(plugins.taskManager, core.elasticsearch.client.asInternalUser) + .catch(() => {}); const logger = appContextService.getLogger(); @@ -686,7 +688,7 @@ export class FleetPlugin ); // initialize (generate/encrypt/validate) Uninstall Tokens asynchronously - this.initializeUninstallTokens(); + this.initializeUninstallTokens().catch(() => {}); this.fleetStatus$.next({ level: ServiceStatusLevels.available, diff --git a/x-pack/plugins/fleet/server/routes/index.ts b/x-pack/plugins/fleet/server/routes/index.ts index d03703af22bb7..5177b85d84dea 100644 --- a/x-pack/plugins/fleet/server/routes/index.ts +++ b/x-pack/plugins/fleet/server/routes/index.ts @@ -27,7 +27,7 @@ import { registerRoutes as registerFleetProxiesRoutes } from './fleet_proxies'; import { registerRoutes as registerMessageSigningServiceRoutes } from './message_signing_service'; import { registerRoutes as registerUninstallTokenRoutes } from './uninstall_token'; -export async function registerRoutes(fleetAuthzRouter: FleetAuthzRouter, config: FleetConfigType) { +export function registerRoutes(fleetAuthzRouter: FleetAuthzRouter, config: FleetConfigType) { // Always register app routes for permissions checking registerAppRoutes(fleetAuthzRouter); diff --git a/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts index f541212a51ab1..1c569270a3c9d 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_create.test.ts @@ -192,15 +192,17 @@ describe('createAgentPolicyWithPackages', () => { it('should call deploy policy once when create policy with system package', async () => { mockedAgentPolicyService.deployPolicy.mockClear(); - mockedAgentPolicyService.create.mockImplementation((soClient, esClient, newPolicy, options) => { - if (!options?.skipDeploy) { - mockedAgentPolicyService.deployPolicy(soClientMock, 'new_id'); + mockedAgentPolicyService.create.mockImplementation( + async (soClient, esClient, newPolicy, options) => { + if (!options?.skipDeploy) { + await mockedAgentPolicyService.deployPolicy(soClientMock, 'new_id'); + } + return Promise.resolve({ + ...newPolicy, + id: options?.id || 'new_id', + } as AgentPolicy); } - return Promise.resolve({ - ...newPolicy, - id: options?.id || 'new_id', - } as AgentPolicy); - }); + ); const response = await createAgentPolicyWithPackages({ esClient: esClientMock, soClient: soClientMock, diff --git a/x-pack/plugins/fleet/server/services/agents/action_runner.ts b/x-pack/plugins/fleet/server/services/agents/action_runner.ts index d8834d5306a92..3abe4787e6132 100644 --- a/x-pack/plugins/fleet/server/services/agents/action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/action_runner.ts @@ -83,12 +83,12 @@ export abstract class ActionRunner { // create task to check result with some delay, this runs in case of kibana crash too this.checkTaskId = await this.createCheckResultTask(); - withSpan({ name: this.getActionType(), type: 'action' }, () => + await withSpan({ name: this.getActionType(), type: 'action' }, () => this.processAgentsInBatches() - .then(() => { + .then(async () => { if (this.checkTaskId) { // no need for check task, action succeeded - this.bulkActionsResolver!.removeIfExists(this.checkTaskId); + await this.bulkActionsResolver!.removeIfExists(this.checkTaskId); } }) .catch(async (error) => { @@ -233,7 +233,7 @@ export abstract class ActionRunner { allAgentsProcessed += currentAgents.length; if (this.checkTaskId) { // updating check task with latest checkpoint (this.retryParams.searchAfter) - this.bulkActionsResolver?.removeIfExists(this.checkTaskId); + await this.bulkActionsResolver?.removeIfExists(this.checkTaskId); this.checkTaskId = await this.createCheckResultTask(); } } diff --git a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts index 782b044a84697..8c711099264f4 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts @@ -355,7 +355,7 @@ describe('When using the artifacts services', () => { describe('and calling `deleteArtifact()`', () => { it('should delete the artifact', async () => { - deleteArtifact(esClientMock, '123'); + await deleteArtifact(esClientMock, '123'); expect(esClientMock.delete).toHaveBeenCalledWith({ index: FLEET_SERVER_ARTIFACTS_INDEX, @@ -375,7 +375,7 @@ describe('When using the artifacts services', () => { describe('and calling `bulkDeleteArtifacts()`', () => { it('should delete single artifact', async () => { - bulkDeleteArtifacts(esClientMock, ['123']); + await bulkDeleteArtifacts(esClientMock, ['123']); expect(esClientMock.bulk).toHaveBeenCalledWith({ refresh: 'wait_for', @@ -391,7 +391,7 @@ describe('When using the artifacts services', () => { }); it('should delete all the artifacts', async () => { - bulkDeleteArtifacts(esClientMock, ['123', '231']); + await bulkDeleteArtifacts(esClientMock, ['123', '231']); expect(esClientMock.bulk).toHaveBeenCalledWith({ refresh: 'wait_for', diff --git a/x-pack/plugins/fleet/server/services/download_source.test.ts b/x-pack/plugins/fleet/server/services/download_source.test.ts index e244ec80077b2..1e9c7275c8430 100644 --- a/x-pack/plugins/fleet/server/services/download_source.test.ts +++ b/x-pack/plugins/fleet/server/services/download_source.test.ts @@ -291,12 +291,12 @@ describe('Download Service', () => { }); describe('requireUniqueName', () => { - it('throws an error if the name already exists', () => { + it('throws an error if the name already exists', async () => { const soClient = getMockedSoClient({ defaultDownloadSourceId: 'download-source-test', sameName: true, }); - expect( + await expect( async () => await downloadSourceService.requireUniqueName(soClient, { name: 'Test' }) ).rejects.toThrow(`Download Source 'download-source-test' already exists with name 'Test'`); }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts index 84c2457f4dafe..17118aa06b199 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts @@ -24,9 +24,9 @@ export async function untarBuffer( const inflateStream = tar.list().on('entry', (entry) => { const path = entry.path || ''; if (!filter({ path })) return; - streamToBuffer(entry as unknown as NodeJS.ReadableStream).then((entryBuffer) => - onEntry({ buffer: entryBuffer, path }) - ); + streamToBuffer(entry as unknown as NodeJS.ReadableStream) + .then((entryBuffer) => onEntry({ buffer: entryBuffer, path })) + .catch(() => {}); }); deflatedStream.pipe(inflateStream); diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.test.ts b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.test.ts index 06b09e15951c4..3547fc70daa15 100644 --- a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.test.ts @@ -93,7 +93,7 @@ describe('installKibanaSavedObjects', () => { mockImporter.import.mockResolvedValueOnce(errorResponse).mockResolvedValueOnce(successResponse); - expect( + await expect( installKibanaSavedObjects({ savedObjectsImporter: mockImporter, logger: mockLogger, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts index 7568dafe248ac..dec78b3be7d5c 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts @@ -325,7 +325,7 @@ describe('_installPackage', () => { describe('timeout not reached', () => { describe('force flag not provided', () => { it('throws concurrent installation error if force flag is not provided', async () => { - expect( + await expect( _installPackage({ savedObjectsClient: soClient, // @ts-ignore @@ -386,7 +386,7 @@ describe('_installPackage', () => { }); }); - it('surfaces saved object conflicts error', () => { + it('surfaces saved object conflicts error', async () => { appContextService.start( createAppContextStartContractMock({ internal: { @@ -407,7 +407,7 @@ describe('_installPackage', () => { new PackageSavedObjectConflictError('test') ); - expect( + await expect( _installPackage({ savedObjectsClient: soClient, // @ts-ignore diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index c8c2e542bfe8b..c5ce7e5f0eca8 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -1279,7 +1279,7 @@ export const saveKibanaAssetsRefs = async ( // Because Kibana assets are installed in parallel with ES assets with refresh: false, we almost always run into an // issue that causes a conflict error due to this issue: https://github.com/elastic/kibana/issues/126240. This is safe // to retry constantly until it succeeds to optimize this critical user journey path as much as possible. - pRetry( + await pRetry( () => savedObjectsClient.update( PACKAGES_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts index 8b129e6fe2f6c..6de0577e33238 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts @@ -153,7 +153,7 @@ describe('fetch package', () => { mockGetBundledPackageByName.mockResolvedValue(bundledPackage); - expect(() => fetchFindLatestPackageOrThrow('testpkg')).rejects.toBeInstanceOf( + await expect(() => fetchFindLatestPackageOrThrow('testpkg')).rejects.toBeInstanceOf( PackageNotFoundError ); }); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/requests.test.ts b/x-pack/plugins/fleet/server/services/epm/registry/requests.test.ts index e13ff87bf45e5..e4e34d25671f6 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/requests.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/requests.test.ts @@ -42,7 +42,7 @@ describe('Registry request', () => { (appContextService.getKibanaVersion as jest.Mock).mockReturnValue('8.0.0'); }); it('should set User-Agent header including kibana version', async () => { - getResponse(''); + await getResponse(''); expect(fetchMock).toHaveBeenCalledWith('', { headers: { @@ -54,7 +54,7 @@ describe('Registry request', () => { it('should set User-Agent header including kibana version with agent', async () => { mockRegistryProxyUrl = 'url'; - getResponse(''); + await getResponse(''); expect(fetchMock).toHaveBeenCalledWith('', { agent: 'proxy agent', diff --git a/x-pack/plugins/fleet/server/services/files/index.test.ts b/x-pack/plugins/fleet/server/services/files/index.test.ts index 551cded5d66b2..2991c1dcbd1a6 100644 --- a/x-pack/plugins/fleet/server/services/files/index.test.ts +++ b/x-pack/plugins/fleet/server/services/files/index.test.ts @@ -165,14 +165,14 @@ describe('files service', () => { }); describe('#updateFilesStatus()', () => { - it('calls esClient.updateByQuery with expected values', () => { + it('calls esClient.updateByQuery with expected values', async () => { const FAKE_INTEGRATION_METADATA_INDEX = getFileMetadataIndexName('someintegration'); const files = { [ENDPOINT_FILE_METADATA_INDEX]: new Set(['delete1', 'delete2']), [FAKE_INTEGRATION_METADATA_INDEX]: new Set(['delete2', 'delete3']), }; const status = 'DELETED'; - updateFilesStatus(esClientMock, abortController, files, status); + await updateFilesStatus(esClientMock, abortController, files, status); expect(esClientMock.updateByQuery).toHaveBeenNthCalledWith( 1, diff --git a/x-pack/plugins/fleet/server/services/fleet_proxies.ts b/x-pack/plugins/fleet/server/services/fleet_proxies.ts index 61aa07b8e0614..4cfc81db50740 100644 --- a/x-pack/plugins/fleet/server/services/fleet_proxies.ts +++ b/x-pack/plugins/fleet/server/services/fleet_proxies.ts @@ -201,32 +201,30 @@ async function updateRelatedSavedObject( ) { await pMap( fleetServerHosts, - (fleetServerHost) => { + (fleetServerHost) => updateFleetServerHost(soClient, fleetServerHost.id, { ...omit(fleetServerHost, 'id'), proxy_id: null, - }); - }, + }), { concurrency: 20 } ); await pMap( outputs, - (output) => { + (output) => outputService.update(soClient, esClient, output.id, { ...omit(output, 'id'), proxy_id: null, - } as Partial); - }, + } as Partial), { concurrency: 20 } ); - await pMap(downloadSources, (downloadSource) => { + await pMap(downloadSources, (downloadSource) => downloadSourceService.update(soClient, downloadSource.id, { ...omit(downloadSource, 'id'), proxy_id: null, - }); - }); + }) + ); } export async function getFleetProxyRelatedSavedObjects( diff --git a/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts b/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts index 92a1dc6da33cf..76c4aba77038c 100644 --- a/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts +++ b/x-pack/plugins/fleet/server/services/fleet_usage_logger.ts @@ -17,7 +17,7 @@ import { appContextService } from './app_context'; const TASK_ID = 'Fleet-Usage-Logger-Task'; const TASK_TYPE = 'Fleet-Usage-Logger'; -export async function registerFleetUsageLogger( +export function registerFleetUsageLogger( taskManager: TaskManagerSetupContract, fetchUsage: () => ReturnType ) { diff --git a/x-pack/plugins/fleet/server/services/output.test.ts b/x-pack/plugins/fleet/server/services/output.test.ts index 13409f7e6f1d4..887a0ac9e0c8f 100644 --- a/x-pack/plugins/fleet/server/services/output.test.ts +++ b/x-pack/plugins/fleet/server/services/output.test.ts @@ -522,7 +522,7 @@ describe('Output Service', () => { it('should throw an error when preset: balanced is provided but config_yaml contains a reserved key', async () => { const soClient = getMockedSoClient({}); - expect( + await expect( outputService.create( soClient, esClientMock, @@ -879,7 +879,7 @@ describe('Output Service', () => { defaultOutputId: 'output-test', }); - expect( + await expect( outputService.create( soClient, esClientMock, @@ -1703,7 +1703,7 @@ describe('Output Service', () => { defaultOutputId: 'output-test', }); - expect( + await expect( outputService.update(soClient, esClientMock, 'output-test', { is_default: true, is_default_monitoring: false, diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index cc605900c3a58..9d288049f67df 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -2888,7 +2888,7 @@ describe('Package policy service', () => { it('should fail to return the package policy', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - expect( + await expect( packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, @@ -4905,7 +4905,7 @@ describe('Package policy service', () => { it('should return error if package policy newer than package version', async () => { mockPackage('aws'); - expect( + await expect( packagePolicyService.getUpgradePackagePolicyInfo(savedObjectsClient, 'package-policy-id') ).rejects.toEqual( new PackagePolicyIneligibleForUpgradeError( @@ -4917,7 +4917,7 @@ describe('Package policy service', () => { it('should return error if package not installed', async () => { mockPackage('notinstalled'); - expect( + await expect( packagePolicyService.getUpgradePackagePolicyInfo(savedObjectsClient, 'package-policy-id') ).rejects.toEqual(new FleetError('Package notinstalled is not installed')); }); diff --git a/x-pack/plugins/fleet/server/services/security/message_signing_service.ts b/x-pack/plugins/fleet/server/services/security/message_signing_service.ts index 741b9e33dec88..9e3ec0f0bbc21 100644 --- a/x-pack/plugins/fleet/server/services/security/message_signing_service.ts +++ b/x-pack/plugins/fleet/server/services/security/message_signing_service.ts @@ -234,7 +234,7 @@ export class MessageSigningService implements MessageSigningServiceInterface { soDoc = result.saved_objects[0]; break; } - finder.close(); + await finder.close(); if (soDoc?.error) { throw soDoc.error; diff --git a/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts b/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts index 7b9da34315418..63753401cc417 100644 --- a/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts +++ b/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts @@ -352,7 +352,7 @@ export class UninstallTokenService implements UninstallTokenServiceInterface { tokenObjects = result.saved_objects; break; } - tokensFinder.close(); + await tokensFinder.close(); return tokenObjects; } @@ -497,7 +497,7 @@ export class UninstallTokenService implements UninstallTokenServiceInterface { if (force) { const config = appContextService.getConfig(); const batchSize = config?.setup?.agentPolicySchemaUpgradeBatchSize ?? 100; - asyncForEach( + await asyncForEach( chunk(policyIds, batchSize), async (policyIdsBatch) => await agentPolicyService.deployPolicies(this.soClient, policyIdsBatch) diff --git a/x-pack/plugins/fleet/server/telemetry/sender.test.ts b/x-pack/plugins/fleet/server/telemetry/sender.test.ts index 74e3e1dba1319..0f79cd8464e3e 100644 --- a/x-pack/plugins/fleet/server/telemetry/sender.test.ts +++ b/x-pack/plugins/fleet/server/telemetry/sender.test.ts @@ -29,7 +29,7 @@ describe('TelemetryEventsSender', () => { let logger: ReturnType; let sender: TelemetryEventsSender; - beforeEach(() => { + beforeEach(async () => { logger = loggingSystemMock.createLogger(); sender = new TelemetryEventsSender(logger); sender['fetchClusterInfo'] = jest.fn(async () => { @@ -41,7 +41,7 @@ describe('TelemetryEventsSender', () => { }, } as InfoResponse; }); - sender.start(undefined, { + await sender.start(undefined, { elasticsearch: { client: { asInternalUser: { info: jest.fn(async () => ({})) } } }, } as any); }); diff --git a/x-pack/plugins/fleet/server/telemetry/sender.ts b/x-pack/plugins/fleet/server/telemetry/sender.ts index 7684284165ee1..d50464b1a34e1 100644 --- a/x-pack/plugins/fleet/server/telemetry/sender.ts +++ b/x-pack/plugins/fleet/server/telemetry/sender.ts @@ -14,6 +14,8 @@ import axios from 'axios'; import type { InfoResponse } from '@elastic/elasticsearch/lib/api/types'; +import { exhaustMap, Subject, takeUntil, timer } from 'rxjs'; + import { TelemetryQueue } from './queue'; import type { FleetTelemetryChannel, FleetTelemetryChannelEvents } from './types'; @@ -26,10 +28,10 @@ export class TelemetryEventsSender { private readonly initialCheckDelayMs = 10 * 1000; private readonly checkIntervalMs = 30 * 1000; private readonly logger: Logger; + private readonly stop$ = new Subject(); private telemetryStart?: TelemetryPluginStart; private telemetrySetup?: TelemetryPluginSetup; - private intervalId?: NodeJS.Timeout; private isSending = false; private queuesPerChannel: { [channel: string]: TelemetryQueue } = {}; private isOptedIn?: boolean = true; // Assume true until the first check @@ -50,16 +52,16 @@ export class TelemetryEventsSender { this.clusterInfo = await this.fetchClusterInfo(); this.logger.debug(`Starting local task`); - setTimeout(() => { - this.sendIfDue(); - this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); - }, this.initialCheckDelayMs); + timer(this.initialCheckDelayMs, this.checkIntervalMs) + .pipe( + takeUntil(this.stop$), + exhaustMap(() => this.sendIfDue()) + ) + .subscribe(); } public stop() { - if (this.intervalId) { - clearInterval(this.intervalId); - } + this.stop$.next(); } public queueTelemetryEvents( diff --git a/x-pack/plugins/license_api_guard/server/license.test.ts b/x-pack/plugins/license_api_guard/server/license.test.ts index 9f20a3e20e995..8beeddfd1d35c 100644 --- a/x-pack/plugins/license_api_guard/server/license.test.ts +++ b/x-pack/plugins/license_api_guard/server/license.test.ts @@ -58,7 +58,14 @@ describe('License API guard', () => { const forbidden = jest.fn(); const responseMock = httpServerMock.createResponseFactory(); responseMock.forbidden = forbidden; - guardedRoute({} as RequestHandlerContext, {} as KibanaRequest, responseMock); + const maybePromise = guardedRoute( + {} as RequestHandlerContext, + {} as KibanaRequest, + responseMock + ); + if (maybePromise instanceof Promise) { + maybePromise.catch(() => {}); + } return { errorResponse: diff --git a/x-pack/plugins/license_management/server/plugin.ts b/x-pack/plugins/license_management/server/plugin.ts index 6368d973a10eb..e1859f84fd162 100644 --- a/x-pack/plugins/license_management/server/plugin.ts +++ b/x-pack/plugins/license_management/server/plugin.ts @@ -35,7 +35,7 @@ export class LicenseManagementServerPlugin ], }); - getStartServices().then(([, { licensing }]) => { + void getStartServices().then(([, { licensing }]) => { this.apiRoutes.setup({ router, plugins: { diff --git a/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_items_point_in_time_finder.ts b/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_items_point_in_time_finder.ts index 8bd79eaa7f3a2..0f9188930c44b 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_items_point_in_time_finder.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_items_point_in_time_finder.ts @@ -118,7 +118,7 @@ export const findExceptionListsItemPointInTimeFinder = async ({ ); executeFunctionOnStream(exceptionListItem); try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal @@ -132,7 +132,7 @@ export const findExceptionListsItemPointInTimeFinder = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_point_in_time_finder.ts b/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_point_in_time_finder.ts index 77869f2f847fa..4fc9bf96d2a7d 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_point_in_time_finder.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/find_exception_list_point_in_time_finder.ts @@ -96,7 +96,7 @@ export const findExceptionListPointInTimeFinder = async ({ exceptionList.data = exceptionList.data.slice(-exceptionList.data.length, -diff); executeFunctionOnStream(exceptionList); try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal @@ -109,7 +109,7 @@ export const findExceptionListPointInTimeFinder = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/lists/server/services/exception_lists/find_value_list_exception_list_items_point_in_time_finder.ts b/x-pack/plugins/lists/server/services/exception_lists/find_value_list_exception_list_items_point_in_time_finder.ts index bc34bb18162f7..b216d02437e2a 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/find_value_list_exception_list_items_point_in_time_finder.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/find_value_list_exception_list_items_point_in_time_finder.ts @@ -95,7 +95,7 @@ export const findValueListExceptionListItemsPointInTimeFinder = async ({ exceptionList.data = exceptionList.data.slice(-exceptionList.data.length, -diff); executeFunctionOnStream(exceptionList); try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal @@ -108,7 +108,7 @@ export const findValueListExceptionListItemsPointInTimeFinder = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 635638d51f303..93218b6370e80 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -590,7 +590,7 @@ export class DataRecognizer { } } // merge all the save results - this._updateResults(results, saveResults); + await this._updateResults(results, saveResults); return results; } diff --git a/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts b/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts index 8889f6b9572d1..b72ad7d1a4fed 100644 --- a/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts +++ b/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts @@ -94,7 +94,7 @@ export function modelSnapshotProvider(client: IScopedClusterClient, mlClient: Ml await cm.newCalendar(calendar); } - forceStartDatafeeds( + await forceStartDatafeeds( [datafeedId], +snapshot.model_snapshots[0].latest_record_time_stamp!, end diff --git a/x-pack/plugins/ml/server/models/json_schema_service/json_schema_service.ts b/x-pack/plugins/ml/server/models/json_schema_service/json_schema_service.ts index ca6e2a0b18b48..86cfd6a0ff7d2 100644 --- a/x-pack/plugins/ml/server/models/json_schema_service/json_schema_service.ts +++ b/x-pack/plugins/ml/server/models/json_schema_service/json_schema_service.ts @@ -119,10 +119,12 @@ export class JsonSchemaService { Fs.readFileSync(Path.resolve(__dirname, 'openapi_source.json'), 'utf8') ); - supportedEndpoints.forEach((e) => { - // need to extract schema in order to keep required components - this.extractSchema(e.path, e.method, schema); - }); + await Promise.all( + supportedEndpoints.map(async (e) => { + // need to extract schema in order to keep required components + await this.extractSchema(e.path, e.method, schema); + }) + ); for (const pathName in schema.paths) { if (!schema.paths.hasOwnProperty(pathName)) continue; diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index ee36bd7382843..aa42a3e18143c 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -342,10 +342,16 @@ export class MlServerPlugin this.security, this.spacesPlugin !== undefined ); - initializeJobs().finally(() => { - this.setMlReady(); + initializeJobs() + .catch((err) => { + this.log.debug(`Error initializing jobs`, err); + }) + .finally(() => { + this.setMlReady(); + }); + this.savedObjectsSyncService.scheduleSyncTask(plugins.taskManager, coreStart).catch((err) => { + this.log.debug(`Error scheduling saved objects sync task`, err); }); - this.savedObjectsSyncService.scheduleSyncTask(plugins.taskManager, coreStart); }); } diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts index 5228eb488b1f7..f166673258848 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Observable, Subscription } from 'rxjs'; +import { exhaustMap, type Observable, Subject, type Subscription, takeUntil, timer } from 'rxjs'; import { firstValueFrom } from 'rxjs'; import moment from 'moment'; import type { @@ -67,7 +67,7 @@ export class BulkUploader implements IBulkUploader { private kibanaStatusSubscription?: Subscription; private readonly opsMetrics$: Observable; private kibanaStatus: ServiceStatusLevel | null; - private _timer: NodeJS.Timeout | null; + private readonly stop$ = new Subject(); private readonly _interval: number; private readonly config: MonitoringConfig; @@ -86,7 +86,6 @@ export class BulkUploader implements IBulkUploader { this.opsMetrics$ = opsMetrics$; this.config = config; - this._timer = null; this._interval = interval; this._log = log; @@ -108,15 +107,12 @@ export class BulkUploader implements IBulkUploader { this.kibanaStatus = nextStatus.level; }); - if (this._timer) { - clearInterval(this._timer); - } else { - this._fetchAndUpload(esClient); // initial fetch - } - - this._timer = setInterval(() => { - this._fetchAndUpload(esClient); - }, this._interval); + timer(0, this._interval) + .pipe( + takeUntil(this.stop$), + exhaustMap(() => this._fetchAndUpload(esClient)) + ) + .subscribe(); } /* @@ -125,8 +121,7 @@ export class BulkUploader implements IBulkUploader { * @param {String} logPrefix help give context to the reason for stopping */ public stop(logPrefix?: string) { - if (this._timer) clearInterval(this._timer); - this._timer = null; + this.stop$.next(); this.kibanaStatusSubscription?.unsubscribe(); diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 99cc38e44c0e4..5219c3441b13e 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -257,7 +257,7 @@ export class MonitoringPlugin stop() { if (this.cluster && this.cluster.close) { - this.cluster.close(); + this.cluster.close().catch(() => {}); } if (this.licenseService && this.licenseService.stop) { this.licenseService.stop(); diff --git a/x-pack/plugins/notifications/server/services/connectors_email_service.test.ts b/x-pack/plugins/notifications/server/services/connectors_email_service.test.ts index 2f0a505ba1f55..b2dc7248945b6 100644 --- a/x-pack/plugins/notifications/server/services/connectors_email_service.test.ts +++ b/x-pack/plugins/notifications/server/services/connectors_email_service.test.ts @@ -21,7 +21,7 @@ describe('sendPlainTextEmail()', () => { }); describe('calls the provided ActionsClient#bulkEnqueueExecution() with the appropriate params', () => { - it(`omits the 'relatedSavedObjects' field if no context is provided`, () => { + it(`omits the 'relatedSavedObjects' field if no context is provided`, async () => { const actionsClient = unsecuredActionsClientMock.create(); actionsClient.bulkEnqueueExecution.mockResolvedValueOnce({ errors: false, @@ -40,7 +40,7 @@ describe('sendPlainTextEmail()', () => { message: 'With some contents inside.', }; - email.sendPlainTextEmail(payload); + await email.sendPlainTextEmail(payload); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith(REQUESTER_ID, [ @@ -55,7 +55,7 @@ describe('sendPlainTextEmail()', () => { ]); }); - it(`populates the 'relatedSavedObjects' field if context is provided`, () => { + it(`populates the 'relatedSavedObjects' field if context is provided`, async () => { const actionsClient = unsecuredActionsClientMock.create(); actionsClient.bulkEnqueueExecution.mockResolvedValueOnce({ errors: false, @@ -83,7 +83,7 @@ describe('sendPlainTextEmail()', () => { }, }; - email.sendPlainTextEmail(payload); + await email.sendPlainTextEmail(payload); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith(REQUESTER_ID, [ @@ -168,7 +168,7 @@ describe('sendHTMLEmail()', () => { }); describe('calls the provided ActionsClient#bulkEnqueueExecution() with the appropriate params', () => { - it(`omits the 'relatedSavedObjects' field if no context is provided`, () => { + it(`omits the 'relatedSavedObjects' field if no context is provided`, async () => { const actionsClient = unsecuredActionsClientMock.create(); actionsClient.bulkEnqueueExecution.mockResolvedValueOnce({ errors: false, @@ -188,7 +188,7 @@ describe('sendHTMLEmail()', () => { messageHTML: 'With some contents inside.', }; - email.sendHTMLEmail(payload); + await email.sendHTMLEmail(payload); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith(REQUESTER_ID, [ @@ -204,7 +204,7 @@ describe('sendHTMLEmail()', () => { ]); }); - it(`populates the 'relatedSavedObjects' field if context is provided`, () => { + it(`populates the 'relatedSavedObjects' field if context is provided`, async () => { const actionsClient = unsecuredActionsClientMock.create(); actionsClient.bulkEnqueueExecution.mockResolvedValueOnce({ errors: false, @@ -233,7 +233,7 @@ describe('sendHTMLEmail()', () => { }, }; - email.sendHTMLEmail(payload); + await email.sendHTMLEmail(payload); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith(REQUESTER_ID, [ diff --git a/x-pack/plugins/notifications/server/services/licensed_email_service.test.ts b/x-pack/plugins/notifications/server/services/licensed_email_service.test.ts index 0571285a226c9..d24a151863c06 100644 --- a/x-pack/plugins/notifications/server/services/licensed_email_service.test.ts +++ b/x-pack/plugins/notifications/server/services/licensed_email_service.test.ts @@ -66,7 +66,7 @@ describe('LicensedEmailService', () => { const license$ = new Subject(); const email = new LicensedEmailService(emailServiceMock, license$, 'platinum', logger); - email.sendPlainTextEmail(someEmail); + void email.sendPlainTextEmail(someEmail); expect(emailServiceMock.sendPlainTextEmail).not.toHaveBeenCalled(); license$.next(validLicense); @@ -136,7 +136,7 @@ describe('LicensedEmailService', () => { const license$ = new Subject(); const email = new LicensedEmailService(emailServiceMock, license$, 'platinum', logger); - email.sendHTMLEmail(someHTMLEmail); + void email.sendHTMLEmail(someHTMLEmail); expect(emailServiceMock.sendHTMLEmail).not.toHaveBeenCalled(); license$.next(validLicense); diff --git a/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/index.ts index e63502451f04c..5c976c8a499a7 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/index.ts @@ -110,37 +110,43 @@ export async function createApmTelemetry({ usageCollector.registerCollector(collector); - core.getStartServices().then(async ([_coreStart, pluginsStart]) => { - const { taskManager: taskManagerStart } = pluginsStart as { - taskManager: TaskManagerStartContract; - }; + core + .getStartServices() + .then(async ([_coreStart, pluginsStart]) => { + const { taskManager: taskManagerStart } = pluginsStart as { + taskManager: TaskManagerStartContract; + }; - taskManagerStart.ensureScheduled({ - id: APM_TELEMETRY_TASK_NAME, - taskType: APM_TELEMETRY_TASK_NAME, - schedule: { - interval: '720m', - }, - scope: ['apm'], - params: {}, - state: {}, - }); + await taskManagerStart.ensureScheduled({ + id: APM_TELEMETRY_TASK_NAME, + taskType: APM_TELEMETRY_TASK_NAME, + schedule: { + interval: '720m', + }, + scope: ['apm'], + params: {}, + state: {}, + }); - try { - const currentData = ( - await savedObjectsClient.get(APM_TELEMETRY_SAVED_OBJECT_TYPE, APM_TELEMETRY_SAVED_OBJECT_ID) - ).attributes as { kibanaVersion?: string }; + try { + const currentData = ( + await savedObjectsClient.get( + APM_TELEMETRY_SAVED_OBJECT_TYPE, + APM_TELEMETRY_SAVED_OBJECT_ID + ) + ).attributes as { kibanaVersion?: string }; - if (currentData.kibanaVersion !== kibanaVersion) { - logger.debug( - `Stored telemetry is out of date. Task will run immediately. Stored: ${currentData.kibanaVersion}, expected: ${kibanaVersion}` - ); - await taskManagerStart.runSoon(APM_TELEMETRY_TASK_NAME); - } - } catch (err) { - if (!SavedObjectsErrorHelpers.isNotFoundError(err)) { - logger.warn('Failed to fetch saved telemetry data.'); + if (currentData.kibanaVersion !== kibanaVersion) { + logger.debug( + `Stored telemetry is out of date. Task will run immediately. Stored: ${currentData.kibanaVersion}, expected: ${kibanaVersion}` + ); + await taskManagerStart.runSoon(APM_TELEMETRY_TASK_NAME); + } + } catch (err) { + if (!SavedObjectsErrorHelpers.isNotFoundError(err)) { + logger.warn('Failed to fetch saved telemetry data.'); + } } - } - }); + }) + .catch(() => {}); } diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts index 058897dedd32e..43b31c588f422 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts @@ -69,7 +69,7 @@ describe('APMEventClient', () => { await new Promise((resolve) => { setTimeout(() => { - incomingRequest.on('abort', () => { + void incomingRequest.on('abort', () => { setTimeout(() => { resolve(undefined); }, 100); diff --git a/x-pack/plugins/observability_solution/apm/server/plugin.ts b/x-pack/plugins/observability_solution/apm/server/plugin.ts index 8c2bbb8695452..415fd90af7daa 100644 --- a/x-pack/plugins/observability_solution/apm/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm/server/plugin.ts @@ -76,7 +76,7 @@ export class APMPlugin logger: this.logger, kibanaVersion: this.initContext.env.packageInfo.version, isProd: this.initContext.env.mode.prod, - }); + }).catch(() => {}); } plugins.features.registerKibanaFeature(APM_FEATURE); @@ -127,16 +127,18 @@ export class APMPlugin if (currentConfig.serverlessOnboarding && plugins.customIntegrations) { plugins.customIntegrations?.registerCustomIntegration(apmTutorialCustomIntegration); } else { - apmIndicesPromise.then((apmIndices) => { - plugins.home?.tutorials.registerTutorial( - tutorialProvider({ - apmConfig: currentConfig, - apmIndices, - cloud: plugins.cloud, - isFleetPluginEnabled: !isEmpty(resourcePlugins.fleet), - }) - ); - }); + apmIndicesPromise + .then((apmIndices) => { + plugins.home?.tutorials.registerTutorial( + tutorialProvider({ + apmConfig: currentConfig, + apmIndices, + cloud: plugins.cloud, + isFleetPluginEnabled: !isEmpty(resourcePlugins.fleet), + }) + ); + }) + .catch(() => {}); } const telemetryUsageCounter = diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts index 800dbb4455103..08bc47c44822a 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts @@ -265,7 +265,7 @@ const agentConfigurationSearchRoute = createApmServerRoute({ ); if (willMarkAsApplied) { - markAppliedByAgent({ + await markAppliedByAgent({ id: configuration._id, body: configuration._source, internalESClient, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/create_or_update_custom_link.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/create_or_update_custom_link.test.ts index 97f75f2092710..3b5bf5b3f15a6 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/create_or_update_custom_link.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/create_or_update_custom_link.test.ts @@ -33,8 +33,8 @@ describe('Create or Update Custom link', () => { mockNow(1570737000000); }); - it('creates a new custom link', () => { - createOrUpdateCustomLink({ + it('creates a new custom link', async () => { + await createOrUpdateCustomLink({ customLink, internalESClient: mockInternalESClient, }); @@ -50,8 +50,8 @@ describe('Create or Update Custom link', () => { }, }); }); - it('update a new custom link', () => { - createOrUpdateCustomLink({ + it('update a new custom link', async () => { + await createOrUpdateCustomLink({ customLinkId: 'bar', customLink, internalESClient: mockInternalESClient, diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts b/x-pack/plugins/observability_solution/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts index 8b87b52dee166..9b6e34dac783a 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts @@ -35,8 +35,8 @@ describe('migrateLegacyAPMIndicesToSpaceAware', () => { }, } as unknown as CoreStart; - it('does not save any new saved object', () => { - migrateLegacyAPMIndicesToSpaceAware({ + it('does not save any new saved object', async () => { + await migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger: loggerMock, }); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/plugin.ts b/x-pack/plugins/observability_solution/asset_manager/server/plugin.ts index 6ea93a4302f49..73b2cbe87c138 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/plugin.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/plugin.ts @@ -80,7 +80,7 @@ export class AssetManagerServerPlugin esClient: core.elasticsearch.client.asInternalUser, template: assetsIndexTemplateConfig, logger: this.logger, - }); + }).catch(() => {}); // it shouldn't reject, but just in case return {}; } diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts index d1fbef7a7095e..b3ba3c5b184a9 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts @@ -82,7 +82,7 @@ const groupActionVariableDescription = i18n.translate( } ); -export async function registerInventoryThresholdRuleType( +export function registerInventoryThresholdRuleType( alertingPlugin: PluginSetupContract, libs: InfraBackendLibs, { featureFlags }: InfraConfig diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts index f16e7dfd284d2..fa90cc6bf50fd 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts @@ -102,7 +102,7 @@ const viewInAppUrlActionVariableDescription = i18n.translate( } ); -export async function registerLogThresholdRuleType( +export function registerLogThresholdRuleType( alertingPlugin: PluginSetupContract, libs: InfraBackendLibs, { featureFlags }: InfraConfig diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts index e7ea693a0e74d..1adcd58f42592 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts @@ -55,7 +55,7 @@ export type MetricThresholdAlertType = Omit & { ActionGroupIdsOf: MetricThresholdAllowedActionGroups; }; -export async function registerMetricThresholdRuleType( +export function registerMetricThresholdRuleType( alertingPlugin: PluginSetupContract, libs: InfraBackendLibs, { featureFlags }: InfraConfig diff --git a/x-pack/plugins/observability_solution/logs_shared/server/services/log_entries/log_entries_service.ts b/x-pack/plugins/observability_solution/logs_shared/server/services/log_entries/log_entries_service.ts index b9270f5ab38ae..61810c47ff8d2 100644 --- a/x-pack/plugins/observability_solution/logs_shared/server/services/log_entries/log_entries_service.ts +++ b/x-pack/plugins/observability_solution/logs_shared/server/services/log_entries/log_entries_service.ts @@ -21,7 +21,7 @@ export class LogEntriesService { core: CoreSetup, setupDeps: LogEntriesServiceSetupDeps ) { - core.getStartServices().then(([, startDeps, selfStartDeps]) => { + void core.getStartServices().then(([, startDeps, selfStartDeps]) => { setupDeps.data.search.registerSearchStrategy( LOG_ENTRIES_SEARCH_STRATEGY, logEntriesSearchStrategyProvider({ ...setupDeps, ...startDeps, ...selfStartDeps }) diff --git a/x-pack/plugins/observability_solution/observability/server/plugin.ts b/x-pack/plugins/observability_solution/observability/server/plugin.ts index 7b2f36d27fe4a..a9ae78ee146ae 100644 --- a/x-pack/plugins/observability_solution/observability/server/plugin.ts +++ b/x-pack/plugins/observability_solution/observability/server/plugin.ts @@ -282,7 +282,7 @@ export class ObservabilityPlugin implements Plugin { logsExplorerLocator, }); - core.getStartServices().then(([coreStart, pluginStart]) => { + void core.getStartServices().then(([coreStart, pluginStart]) => { registerRoutes({ core, config, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.ts index 969bc5add78b1..0f520102aac2d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/bedrock/process_bedrock_stream.ts @@ -74,7 +74,7 @@ export function processBedrockStream() { subscriber.error(err); }, complete: () => { - nextPromise.then(() => subscriber.complete()); + nextPromise.then(() => subscriber.complete()).catch(() => {}); }, }); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts index e22f63cf92eb2..7bd31f0ef7689 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts @@ -236,7 +236,8 @@ describe('Observability AI Assistant client', () => { status: 'ok', data: titleLlmSimulator.stream, }); - }); + }) + .catch(reject); }; titleLlmPromiseReject = (error: Error) => { reject(error); diff --git a/x-pack/plugins/observability_solution/profiling/server/plugin.ts b/x-pack/plugins/observability_solution/profiling/server/plugin.ts index 5bb7cfe978cc0..27fbc4f958da1 100644 --- a/x-pack/plugins/observability_solution/profiling/server/plugin.ts +++ b/x-pack/plugins/observability_solution/profiling/server/plugin.ts @@ -46,41 +46,44 @@ export class ProfilingPlugin PROFILING_SERVER_FEATURE_ID ); - core.getStartServices().then(([coreStart, depsStart]) => { - const profilingSpecificEsClient = config.elasticsearch - ? coreStart.elasticsearch.createClient('profiling', { - hosts: [config.elasticsearch.hosts], - username: config.elasticsearch.username, - password: config.elasticsearch.password, - }) - : undefined; + core + .getStartServices() + .then(([coreStart, depsStart]) => { + const profilingSpecificEsClient = config.elasticsearch + ? coreStart.elasticsearch.createClient('profiling', { + hosts: [config.elasticsearch.hosts], + username: config.elasticsearch.username, + password: config.elasticsearch.password, + }) + : undefined; - registerRoutes({ - router, - logger: this.logger!, - dependencies: { - start: depsStart, - setup: deps, - config, - stackVersion, - telemetryUsageCounter, - }, - services: { - createProfilingEsClient: ({ - request, - esClient: defaultEsClient, - useDefaultAuth = false, - }) => { - const esClient = - profilingSpecificEsClient && !useDefaultAuth - ? profilingSpecificEsClient.asScoped(request).asInternalUser - : defaultEsClient; + registerRoutes({ + router, + logger: this.logger!, + dependencies: { + start: depsStart, + setup: deps, + config, + stackVersion, + telemetryUsageCounter, + }, + services: { + createProfilingEsClient: ({ + request, + esClient: defaultEsClient, + useDefaultAuth = false, + }) => { + const esClient = + profilingSpecificEsClient && !useDefaultAuth + ? profilingSpecificEsClient.asScoped(request).asInternalUser + : defaultEsClient; - return createProfilingEsClient({ request, esClient }); + return createProfilingEsClient({ request, esClient }); + }, }, - }, - }); - }); + }); + }) + .catch(() => {}); return {}; } diff --git a/x-pack/plugins/observability_solution/slo/server/plugin.ts b/x-pack/plugins/observability_solution/slo/server/plugin.ts index 668d7cc6a51be..6fe07b89bf342 100644 --- a/x-pack/plugins/observability_solution/slo/server/plugin.ts +++ b/x-pack/plugins/observability_solution/slo/server/plugin.ts @@ -29,7 +29,6 @@ import { SpacesPluginSetup, SpacesPluginStart } from '@kbn/spaces-plugin/server' import { AlertsLocatorDefinition } from '@kbn/observability-plugin/common'; import { SLO_BURN_RATE_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { sloFeatureId } from '@kbn/observability-plugin/common'; -import { ServerlessPluginStart } from '@kbn/serverless/server'; import { registerSloUsageCollector } from './lib/collectors/register'; import { SloOrphanSummaryCleanupTask } from './services/tasks/orphan_summary_cleanup_task'; import { slo, SO_SLO_TYPE } from './saved_objects'; @@ -57,7 +56,6 @@ export interface PluginStart { alerting: PluginStartContract; taskManager: TaskManagerStartContract; spaces?: SpacesPluginStart; - serverless: ServerlessPluginStart; } const sloRuleTypes = [SLO_BURN_RATE_RULE_TYPE_ID]; @@ -138,32 +136,42 @@ export class SloPlugin implements Plugin { registerSloUsageCollector(plugins.usageCollection); - core.getStartServices().then(([coreStart, pluginStart]) => { - registerRoutes({ - core, - config, - dependencies: { - pluginsSetup: { - ...plugins, - core, - }, - spaces: pluginStart.spaces, - ruleDataService, - getRulesClientWithRequest: pluginStart.alerting.getRulesClientWithRequest, + registerRoutes({ + core, + config, + dependencies: { + pluginsSetup: { + ...plugins, + core, }, - logger: this.logger, - repository: getSloServerRouteRepository({ - isServerless: !!pluginStart.serverless, - }), - }); - - const esInternalClient = coreStart.elasticsearch.client.asInternalUser; - - const sloResourceInstaller = new DefaultResourceInstaller(esInternalClient, this.logger); - const sloInstaller = new DefaultSLOInstaller(sloResourceInstaller, this.logger); - sloInstaller.install(); + getSpacesStart: async () => { + const [, pluginStart] = await core.getStartServices(); + return pluginStart.spaces; + }, + ruleDataService, + getRulesClientWithRequest: async (request) => { + const [, pluginStart] = await core.getStartServices(); + return pluginStart.alerting.getRulesClientWithRequest(request); + }, + }, + logger: this.logger, + repository: getSloServerRouteRepository({ + isServerless: this.initContext.env.packageInfo.buildFlavor === 'serverless', + }), }); + core + .getStartServices() + .then(async ([coreStart, pluginStart]) => { + const esInternalClient = coreStart.elasticsearch.client.asInternalUser; + const sloResourceInstaller = new DefaultResourceInstaller(esInternalClient, this.logger); + const sloInstaller = new DefaultSLOInstaller(sloResourceInstaller, this.logger); + await sloInstaller.install(); + }) + .catch((error) => { + this.logger.error(`Failed to install the default SLOs: ${error}`); + }); + this.sloOrphanCleanupTask = new SloOrphanSummaryCleanupTask( plugins.taskManager, this.logger, @@ -175,7 +183,9 @@ export class SloPlugin implements Plugin { const internalSoClient = new SavedObjectsClient(core.savedObjects.createInternalRepository()); const internalEsClient = core.elasticsearch.client.asInternalUser; - this.sloOrphanCleanupTask?.start(plugins.taskManager, internalSoClient, internalEsClient); + this.sloOrphanCleanupTask + ?.start(plugins.taskManager, internalSoClient, internalEsClient) + .catch(() => {}); } public stop() {} diff --git a/x-pack/plugins/observability_solution/slo/server/routes/register_routes.ts b/x-pack/plugins/observability_solution/slo/server/routes/register_routes.ts index 66f255a2397b7..83f5ce796e70d 100644 --- a/x-pack/plugins/observability_solution/slo/server/routes/register_routes.ts +++ b/x-pack/plugins/observability_solution/slo/server/routes/register_routes.ts @@ -34,9 +34,9 @@ export interface RegisterRoutesDependencies { pluginsSetup: { core: CoreSetup; }; - spaces?: SpacesPluginStart; + getSpacesStart: () => Promise; ruleDataService: RuleDataPluginService; - getRulesClientWithRequest: (request: KibanaRequest) => RulesClientApi; + getRulesClientWithRequest: (request: KibanaRequest) => Promise; } export function registerRoutes({ config, repository, core, logger, dependencies }: RegisterRoutes) { diff --git a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts index 1853d09c81f54..d71a65e95013a 100644 --- a/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts +++ b/x-pack/plugins/observability_solution/slo/server/routes/slo/route.ts @@ -98,8 +98,8 @@ const createSLORoute = createSloServerRoute({ handler: async ({ context, params, logger, dependencies, request }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const basePath = dependencies.pluginsSetup.core.http.basePath; @@ -143,8 +143,8 @@ const inspectSLORoute = createSloServerRoute({ handler: async ({ context, params, logger, dependencies, request }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const basePath = dependencies.pluginsSetup.core.http.basePath; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const soClient = (await context.core).savedObjects.client; @@ -185,8 +185,8 @@ const updateSLORoute = createSloServerRoute({ handler: async ({ context, request, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const basePath = dependencies.pluginsSetup.core.http.basePath; const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -231,12 +231,12 @@ const deleteSLORoute = createSloServerRoute({ handler: async ({ request, context, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const soClient = (await context.core).savedObjects.client; - const rulesClient = dependencies.getRulesClientWithRequest(request); + const rulesClient = await dependencies.getRulesClientWithRequest(request); const repository = new KibanaSavedObjectsSLORepository(soClient, logger); const transformManager = new DefaultTransformManager( @@ -274,8 +274,8 @@ const getSLORoute = createSloServerRoute({ handler: async ({ request, context, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -298,8 +298,8 @@ const enableSLORoute = createSloServerRoute({ handler: async ({ request, context, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -335,8 +335,8 @@ const disableSLORoute = createSloServerRoute({ handler: async ({ request, context, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -372,8 +372,8 @@ const resetSLORoute = createSloServerRoute({ handler: async ({ context, request, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const basePath = dependencies.pluginsSetup.core.http.basePath; @@ -417,8 +417,8 @@ const findSLORoute = createSloServerRoute({ handler: async ({ context, request, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const repository = new KibanaSavedObjectsSLORepository(soClient, logger); @@ -439,8 +439,8 @@ const findSLOGroupsRoute = createSloServerRoute({ params: findSLOGroupsParamsSchema, handler: async ({ context, request, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService.getActiveSpace(request))?.id ?? 'default'; const soClient = (await context.core).savedObjects.client; const coreContext = context.core; const esClient = (await coreContext).elasticsearch.client.asCurrentUser; @@ -592,8 +592,8 @@ const getSloBurnRates = createSloServerRoute({ handler: async ({ request, context, params, logger, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService.getActiveSpace(request))?.id ?? 'default'; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const soClient = (await context.core).savedObjects.client; @@ -624,8 +624,8 @@ const getPreviewData = createSloServerRoute({ handler: async ({ request, context, params, dependencies }) => { await assertPlatinumLicense(context); - const spaceId = - (await dependencies.spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; + const spaces = await dependencies.getSpacesStart(); + const spaceId = (await spaces?.spacesService?.getActiveSpace(request))?.id ?? 'default'; const esClient = (await context.core).elasticsearch.client.asCurrentUser; const service = new GetPreviewData(esClient, spaceId); diff --git a/x-pack/plugins/observability_solution/slo/server/services/tasks/orphan_summary_cleanup_task.ts b/x-pack/plugins/observability_solution/slo/server/services/tasks/orphan_summary_cleanup_task.ts index 1d9a968dc1ff4..bdbb955050358 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/tasks/orphan_summary_cleanup_task.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/tasks/orphan_summary_cleanup_task.ts @@ -232,7 +232,7 @@ export class SloOrphanSummaryCleanupTask { } if (this.config.sloOrphanSummaryCleanUpTaskEnabled) { - this.taskManager.ensureScheduled({ + await this.taskManager.ensureScheduled({ id: this.taskId, taskType: TASK_TYPE, schedule: { @@ -243,7 +243,7 @@ export class SloOrphanSummaryCleanupTask { params: {}, }); } else { - this.taskManager.removeIfExists(this.taskId); + await this.taskManager.removeIfExists(this.taskId); } } } diff --git a/x-pack/plugins/observability_solution/synthetics/server/lib.ts b/x-pack/plugins/observability_solution/synthetics/server/lib.ts index 6ee70f5282e83..78d88ff6bf51b 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/lib.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/lib.ts @@ -65,7 +65,7 @@ export class UptimeEsClient { this.heartbeatIndices = heartbeatIndices; this.isDev = isDev; this.inspectableEsQueries = []; - this.getInspectEnabled(); + this.getInspectEnabled().catch(() => {}); } async initSettings() { @@ -176,15 +176,14 @@ export class UptimeEsClient { return {}; } async getInspectEnabled() { - if (this.isInspectorEnabled !== undefined) { - return this.isInspectorEnabled; - } - if (!this.uiSettings) { return false; } - this.isInspectorEnabled = this.uiSettings.client.get(enableInspectEsQueries); + if (this.isInspectorEnabled === undefined) { + this.isInspectorEnabled = this.uiSettings.client.get(enableInspectEsQueries); + } + return this.isInspectorEnabled; } async getIndices() { diff --git a/x-pack/plugins/observability_solution/synthetics/server/plugin.ts b/x-pack/plugins/observability_solution/synthetics/server/plugin.ts index 76ac2afcf102b..91331dd124cf1 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/plugin.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/plugin.ts @@ -79,7 +79,7 @@ export class Plugin implements PluginType { this.syntheticsService = new SyntheticsService(this.server); - this.syntheticsService.setup(plugins.taskManager); + this.syntheticsService.setup(plugins.taskManager).catch(() => {}); this.syntheticsMonitorClient = new SyntheticsMonitorClient(this.syntheticsService, this.server); @@ -112,7 +112,7 @@ export class Plugin implements PluginType { this.syntheticsService?.start(pluginsStart.taskManager); - this.telemetryEventsSender.start(pluginsStart.telemetry, coreStart); + this.telemetryEventsSender.start(pluginsStart.telemetry, coreStart).catch(() => {}); } public stop() {} diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor/add_monitor_api.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor/add_monitor_api.ts index 7093b83dab82f..cd105bd0fd831 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor/add_monitor_api.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor/add_monitor_api.ts @@ -259,9 +259,14 @@ export class AddEditMonitorAPI { try { // we do this async, so we don't block the user, error handling will be done on the UI via separate api const defaultAlertService = new DefaultAlertService(context, server, savedObjectsClient); - defaultAlertService.setupDefaultAlerts().then(() => { - server.logger.debug(`Successfully created default alert for monitor: ${name}`); - }); + defaultAlertService + .setupDefaultAlerts() + .then(() => { + server.logger.debug(`Successfully created default alert for monitor: ${name}`); + }) + .catch((error) => { + server.logger.error(`Error creating default alert: ${error} for monitor: ${name}`); + }); } catch (e) { server.logger.error(`Error creating default alert: ${e} for monitor: ${name}`); } diff --git a/x-pack/plugins/observability_solution/synthetics/server/saved_objects/synthetics_monitor/get_all_monitors.ts b/x-pack/plugins/observability_solution/synthetics/server/saved_objects/synthetics_monitor/get_all_monitors.ts index b8e9a08bf3dd1..c742bf26176ad 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/saved_objects/synthetics_monitor/get_all_monitors.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/saved_objects/synthetics_monitor/get_all_monitors.ts @@ -50,8 +50,7 @@ export const getAllMonitors = async ({ hits.push(...result.saved_objects); } - // no need to wait for it - finder.close(); + finder.close().catch(() => {}); return hits; }; diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts index 418fbde0d31db..29b65def487dc 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts @@ -201,7 +201,7 @@ export class SyntheticsPrivateLocation { const result = await this.createPolicyBulk(newPolicies); if (result?.created && result?.created?.length > 0 && testRunId) { // ignore await here, we don't want to wait for this to finish - scheduleCleanUpTask(this.server); + void scheduleCleanUpTask(this.server); } return result; } catch (e) { diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts index 3707b0b9be746..108facf7076a1 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts @@ -258,8 +258,7 @@ export class ProjectMonitorFormatter { ); } - // no need to wait for it - finder.close(); + finder.close().catch(() => {}); return hits; }; diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts index f3b006f3bd241..e9fbe8f0ef3b4 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts @@ -354,8 +354,7 @@ export class SyntheticsMonitorClient { }); } - // no need to wait here - finder.close(); + finder.close().catch(() => {}); return monitors; } diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.test.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.test.ts index 60bc4ab9007e0..e7fcff93c8018 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.test.ts @@ -154,9 +154,12 @@ describe('SyntheticsService', () => { it('setup properly', async () => { const service = new SyntheticsService(serverMock); - service.setup(taskManagerSetup); expect(service.isAllowed).toEqual(false); + + await service.setup(taskManagerSetup); + + expect(service.isAllowed).toEqual(true); expect(service.locations).toEqual([]); expect(service.signupUrl).toEqual(null); }); diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts index fd37aa678ce63..a9e36289b1698 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts @@ -100,9 +100,9 @@ export class SyntheticsService { public start(taskManager: TaskManagerStartContract) { if (this.config?.manifestUrl) { - this.scheduleSyncTask(taskManager); + void this.scheduleSyncTask(taskManager); } - this.setupIndexTemplates(); + void this.setupIndexTemplates(); } public async setupIndexTemplates() { @@ -178,7 +178,7 @@ export class SyntheticsService { service.signupUrl = signupUrl; if (service.isAllowed && service.config.manifestUrl) { - service.setupIndexTemplates(); + void service.setupIndexTemplates(); await service.pushConfigs(); } } catch (e) { @@ -588,7 +588,7 @@ export class SyntheticsService { } // no need to wait here - finder.close(); + finder.close().catch(() => {}); if (paramsBySpace[ALL_SPACES_ID]) { Object.keys(paramsBySpace).forEach((space) => { diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/utils/mocks.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/utils/mocks.ts index b9d6b54961f59..796e92ddbc5b2 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/utils/mocks.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/utils/mocks.ts @@ -24,7 +24,7 @@ export const mockEncryptedSO = ({ createPointInTimeFinderDecryptedAsInternalUser: jest .fn() .mockImplementation(({ perPage, type: soType }) => ({ - close: jest.fn(), + close: jest.fn(async () => {}), find: jest.fn().mockReturnValue({ async *[Symbol.asyncIterator]() { if (soType === syntheticsParamType) { diff --git a/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.test.ts b/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.test.ts index ab599ae0d0ea8..91f859545600b 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.test.ts @@ -57,7 +57,7 @@ describe('TelemetryEventsSender', () => { revision: 1, }; - beforeEach(() => { + beforeEach(async () => { logger = loggingSystemMock.createLogger(); sender = new TelemetryEventsSender(logger); sender['fetchLicenseInfo'] = jest.fn(async () => { @@ -73,7 +73,7 @@ describe('TelemetryEventsSender', () => { }, } as InfoResponse; }); - sender.start(undefined, { + await sender.start(undefined, { elasticsearch: { client: { asInternalUser: { info: jest.fn(async () => ({})) } } }, } as any); }); diff --git a/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.ts b/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.ts index 610f43aa9cfd9..e495181781fe0 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/telemetry/sender.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { exhaustMap, Subject, takeUntil, timer } from 'rxjs'; import type { CoreStart, ElasticsearchClient, Logger } from '@kbn/core/server'; import type { TelemetryPluginStart, TelemetryPluginSetup } from '@kbn/telemetry-plugin/server'; @@ -26,10 +27,10 @@ export class TelemetryEventsSender { private readonly initialCheckDelayMs = 10 * 1000; private readonly checkIntervalMs = 30 * 1000; private readonly logger: Logger; + private readonly stop$ = new Subject(); private telemetryStart?: TelemetryPluginStart; private telemetrySetup?: TelemetryPluginSetup; - private intervalId?: NodeJS.Timeout; private isSending = false; private queuesPerChannel: { [channel: string]: TelemetryQueue } = {}; private isOptedIn?: boolean = true; // Assume true until the first check @@ -52,16 +53,16 @@ export class TelemetryEventsSender { this.licenseInfo = await this.fetchLicenseInfo(); this.logger.debug(`Starting local task`); - setTimeout(() => { - this.sendIfDue(); - this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); - }, this.initialCheckDelayMs); + timer(this.initialCheckDelayMs, this.checkIntervalMs) + .pipe( + takeUntil(this.stop$), + exhaustMap(() => this.sendIfDue()) + ) + .subscribe(); } public stop() { - if (this.intervalId) { - clearInterval(this.intervalId); - } + this.stop$.next(); } public queueTelemetryEvents( diff --git a/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/lib/lib.ts b/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/lib/lib.ts index 15f2530667d7d..5b1326bf7a065 100644 --- a/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/lib/lib.ts +++ b/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/lib/lib.ts @@ -80,7 +80,7 @@ export class UptimeEsClient { this.heartbeatIndices = heartbeatIndices; this.isDev = isDev; this.inspectableEsQueries = []; - this.getInspectEnabled(); + this.getInspectEnabled().catch(() => {}); } async initSettings() { diff --git a/x-pack/plugins/osquery/server/create_transforms/create_transforms.ts b/x-pack/plugins/osquery/server/create_transforms/create_transforms.ts index b3c1b74967721..b365449c75121 100644 --- a/x-pack/plugins/osquery/server/create_transforms/create_transforms.ts +++ b/x-pack/plugins/osquery/server/create_transforms/create_transforms.ts @@ -21,12 +21,12 @@ export const initializeTransform = async ( esClient: ElasticsearchClient, transform: TransformPutTransformRequest, logger: Logger -) => - createTransformIfNotExists(esClient, transform, logger).then((succeeded) => { - if (succeeded) { - startTransformIfNotStarted(esClient, transform.transform_id, logger); - } - }); +) => { + const succeeded = await createTransformIfNotExists(esClient, transform, logger); + if (succeeded) { + await startTransformIfNotStarted(esClient, transform.transform_id, logger); + } +}; /** * Checks if a transform exists, And if not creates it diff --git a/x-pack/plugins/osquery/server/lib/telemetry/receiver.ts b/x-pack/plugins/osquery/server/lib/telemetry/receiver.ts index 0053cd9523135..4749d36522569 100644 --- a/x-pack/plugins/osquery/server/lib/telemetry/receiver.ts +++ b/x-pack/plugins/osquery/server/lib/telemetry/receiver.ts @@ -40,7 +40,7 @@ export class TelemetryReceiver { this.logger = logger.get('telemetry_events'); } - public async start(core: CoreStart, osqueryContextService?: OsqueryAppContextService) { + public start(core: CoreStart, osqueryContextService?: OsqueryAppContextService) { this.agentClient = osqueryContextService?.getAgentService()?.asInternalUser; this.agentPolicyService = osqueryContextService?.getAgentPolicyService(); this.packageService = osqueryContextService?.getPackageService(); diff --git a/x-pack/plugins/osquery/server/lib/update_global_packs.ts b/x-pack/plugins/osquery/server/lib/update_global_packs.ts index 8a3e048532202..2cf48bf59013c 100644 --- a/x-pack/plugins/osquery/server/lib/update_global_packs.ts +++ b/x-pack/plugins/osquery/server/lib/update_global_packs.ts @@ -46,7 +46,7 @@ export const updateGlobalPacksCreateCallback = async ( if (packsContainingShardForPolicy.length) { await Promise.all( - map(packsContainingShardForPolicy, (pack) => { + map(packsContainingShardForPolicy, (pack) => packsClient.update( packSavedObjectType, pack.saved_object_id, @@ -61,8 +61,8 @@ export const updateGlobalPacksCreateCallback = async ( }, ], } - ); - }) + ) + ) ); return produce(packagePolicy, (draft) => { diff --git a/x-pack/plugins/osquery/server/plugin.ts b/x-pack/plugins/osquery/server/plugin.ts index 117feb69fa4b9..9a0772708d133 100644 --- a/x-pack/plugins/osquery/server/plugin.ts +++ b/x-pack/plugins/osquery/server/plugin.ts @@ -80,15 +80,20 @@ export class OsqueryPlugin implements Plugin { - const osquerySearchStrategy = osquerySearchStrategyProvider( - depsStart.data, - elasticsearch.client - ); - - plugins.data.search.registerSearchStrategy('osquerySearchStrategy', osquerySearchStrategy); - defineRoutes(router, osqueryContext); - }); + core + .getStartServices() + .then(([{ elasticsearch }, depsStart]) => { + const osquerySearchStrategy = osquerySearchStrategyProvider( + depsStart.data, + elasticsearch.client + ); + + plugins.data.search.registerSearchStrategy('osquerySearchStrategy', osquerySearchStrategy); + defineRoutes(router, osqueryContext); + }) + .catch(() => { + // it shouldn't reject, but just in case + }); this.telemetryEventsSender.setup(this.telemetryReceiver, plugins.taskManager, core.analytics); @@ -117,64 +122,71 @@ export class OsqueryPlugin implements Plugin { - const packageInfo = await plugins.fleet?.packageService.asInternalUser.getInstallation( - OSQUERY_INTEGRATION_NAME - ); - const client = new SavedObjectsClient(core.savedObjects.createInternalRepository()); - - const esClient = core.elasticsearch.client.asInternalUser; - const dataViewsService = await plugins.dataViews.dataViewsServiceFactory( - client, - esClient, - undefined, - true - ); - - // If package is installed we want to make sure all needed assets are installed - if (packageInfo) { - await this.initialize(core, dataViewsService); - } - - // Upgrade integration into 1.6.0 and rollover if found 'generic' dataset - we do not want to wait for it - upgradeIntegration({ packageInfo, client, esClient, logger: this.logger }); - - if (registerIngestCallback) { - registerIngestCallback( - 'packagePolicyCreate', - async (newPackagePolicy: NewPackagePolicy): Promise => { - if (newPackagePolicy.package?.name === OSQUERY_INTEGRATION_NAME) { - await this.initialize(core, dataViewsService); - - const allPacks = await client - .find({ - type: packSavedObjectType, - }) - .then((data) => ({ - ...data, - saved_objects: data.saved_objects.map((pack) => ({ - ...pack.attributes, - saved_object_id: pack.id, - })), - })); - - if (allPacks.saved_objects) { - return updateGlobalPacksCreateCallback( - newPackagePolicy, - client, - allPacks.saved_objects, - this.osqueryAppContextService - ); - } - } - - return newPackagePolicy; - } + plugins.fleet + ?.fleetSetupCompleted() + .then(async () => { + const packageInfo = await plugins.fleet?.packageService.asInternalUser.getInstallation( + OSQUERY_INTEGRATION_NAME + ); + const client = new SavedObjectsClient(core.savedObjects.createInternalRepository()); + + const esClient = core.elasticsearch.client.asInternalUser; + const dataViewsService = await plugins.dataViews.dataViewsServiceFactory( + client, + esClient, + undefined, + true ); - registerIngestCallback('packagePolicyPostDelete', getPackagePolicyDeleteCallback(client)); - } - }); + // If package is installed we want to make sure all needed assets are installed + if (packageInfo) { + await this.initialize(core, dataViewsService); + } + + // Upgrade integration into 1.6.0 and rollover if found 'generic' dataset - we do not want to wait for it + upgradeIntegration({ packageInfo, client, esClient, logger: this.logger }).catch(() => { + // we do not want to wait for it + }); + + if (registerIngestCallback) { + registerIngestCallback( + 'packagePolicyCreate', + async (newPackagePolicy: NewPackagePolicy): Promise => { + if (newPackagePolicy.package?.name === OSQUERY_INTEGRATION_NAME) { + await this.initialize(core, dataViewsService); + + const allPacks = await client + .find({ + type: packSavedObjectType, + }) + .then((data) => ({ + ...data, + saved_objects: data.saved_objects.map((pack) => ({ + ...pack.attributes, + saved_object_id: pack.id, + })), + })); + + if (allPacks.saved_objects) { + return updateGlobalPacksCreateCallback( + newPackagePolicy, + client, + allPacks.saved_objects, + this.osqueryAppContextService + ); + } + } + + return newPackagePolicy; + } + ); + + registerIngestCallback('packagePolicyPostDelete', getPackagePolicyDeleteCallback(client)); + } + }) + .catch(() => { + // it shouldn't reject, but just in case + }); return {}; } diff --git a/x-pack/plugins/reporting/server/lib/store/store.test.ts b/x-pack/plugins/reporting/server/lib/store/store.test.ts index eef04ad477c45..946ceb4f105b0 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.test.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.test.ts @@ -75,7 +75,7 @@ describe('ReportingStore', () => { payload: {}, meta: {}, } as any); - expect(store.addReport(mockReport)).rejects.toMatchInlineSnapshot( + await expect(store.addReport(mockReport)).rejects.toMatchInlineSnapshot( `[Error: Report object from ES has missing fields!]` ); }); diff --git a/x-pack/plugins/rule_registry/server/plugin.ts b/x-pack/plugins/rule_registry/server/plugin.ts index 8cb6df23ae766..2a430c45b54d8 100644 --- a/x-pack/plugins/rule_registry/server/plugin.ts +++ b/x-pack/plugins/rule_registry/server/plugin.ts @@ -119,20 +119,23 @@ export class RuleRegistryPlugin this.ruleDataService.initializeService(); - core.getStartServices().then(([_, depsStart]) => { - const ruleRegistrySearchStrategy = ruleRegistrySearchStrategyProvider( - depsStart.data, - depsStart.alerting, - logger, - plugins.security, - depsStart.spaces - ); - - plugins.data.search.registerSearchStrategy( - RULE_SEARCH_STRATEGY_NAME, - ruleRegistrySearchStrategy - ); - }); + core + .getStartServices() + .then(([_, depsStart]) => { + const ruleRegistrySearchStrategy = ruleRegistrySearchStrategyProvider( + depsStart.data, + depsStart.alerting, + logger, + plugins.security, + depsStart.spaces + ); + + plugins.data.search.registerSearchStrategy( + RULE_SEARCH_STRATEGY_NAME, + ruleRegistrySearchStrategy + ); + }) + .catch(() => {}); // ALERTS ROUTES const router = core.http.createRouter(); diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.test.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.test.ts index defaed0a7500b..f2cbe8ef5aeb7 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.test.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.test.ts @@ -88,11 +88,11 @@ describe('resourceInstaller', () => { pluginStop$, dataStreamAdapter, }); - installer.installCommonResources(); + await installer.installCommonResources(); expect(getClusterClient).not.toHaveBeenCalled(); }); - it('should not install index level resources', () => { + it('should not install index level resources', async () => { const mockClusterClient = elasticsearchServiceMock.createElasticsearchClient(); const getClusterClient = jest.fn(() => Promise.resolve(mockClusterClient)); @@ -119,7 +119,7 @@ describe('resourceInstaller', () => { }; const indexInfo = new IndexInfo({ indexOptions, kibanaVersion: '8.1.0' }); - installer.installIndexLevelResources(indexInfo); + await installer.installIndexLevelResources(indexInfo); expect(mockClusterClient.cluster.putComponentTemplate).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts index 99454bfe30946..49e7d706b3117 100644 --- a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts +++ b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts @@ -199,8 +199,8 @@ export const ruleRegistrySearchStrategyProvider = ( ); }, cancel: async (id, options, deps) => { - if (internalUserEs.cancel) internalUserEs.cancel(id, options, deps); - if (requestUserEs.cancel) requestUserEs.cancel(id, options, deps); + if (internalUserEs.cancel) internalUserEs.cancel(id, options, deps).catch(() => {}); + if (requestUserEs.cancel) requestUserEs.cancel(id, options, deps).catch(() => {}); }, }; }; diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts index 5727a854ac3ca..fbe118280fe85 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts @@ -386,7 +386,7 @@ export class HeadlessChromiumDriver { errorReason: 'Aborted', requestId, }); - this.page.browser().close(); + void this.page.browser().close(); const error = getDisallowedOutgoingUrlError(interceptedUrl); this.screenshottingErrorSubject.next(error); logger.error(error); @@ -438,7 +438,7 @@ export class HeadlessChromiumDriver { } if (!allowed || !this.allowRequest(interceptedUrl)) { - this.page.browser().close(); + void this.page.browser().close(); const error = getDisallowedOutgoingUrlError(interceptedUrl); this.screenshottingErrorSubject.next(error); logger.error(error); @@ -464,7 +464,7 @@ export class HeadlessChromiumDriver { const wsEndpoint = this.page.browser().wsEndpoint(); const { port } = parseUrl(wsEndpoint); - open( + await open( `http://localhost:${port}/devtools/inspector.html?ws=localhost:${port}/devtools/page/${targetId}` ); } diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.test.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.test.ts index 317614e7733d1..13b9070edb7fb 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.test.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.test.ts @@ -82,7 +82,7 @@ describe('HeadlessChromiumDriverFactory', () => { it('rejects if Puppeteer launch fails', async () => { jest.spyOn(puppeteer, 'launch').mockRejectedValue(`Puppeteer Launch mock fail.`); - expect(() => + await expect(() => factory .createPage({ openUrlTimeout: 0, defaultViewport: DEFAULT_VIEWPORT }) .pipe(take(1)) diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.ts index 1c562a481790e..66a4dac0c37a2 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/driver_factory/index.ts @@ -226,7 +226,7 @@ export class HeadlessChromiumDriverFactory { observer.add(() => { if (page.isClosed()) return; // avoid emitting a log unnecessarily logger.debug(`It looks like the browser is no longer being used. Closing the browser...`); - childProcess.kill(); // ignore async + void childProcess.kill(); // ignore async }); // make the observer subscribe to terminate$ @@ -272,7 +272,7 @@ export class HeadlessChromiumDriverFactory { logger.error(error); }); }); - })(); + })().catch(() => {}); }); } diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts index 8a4571c128f9c..ff58fbf6d8bc5 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts @@ -130,9 +130,9 @@ export async function toPdf( } } else { buffer = results[0].screenshots[0].data; // This buffer is already the PDF - pages = await PDFJS.getDocument({ data: buffer }).promise.then((doc) => { + pages = await PDFJS.getDocument({ data: buffer }).promise.then(async (doc) => { const numPages = doc.numPages; - doc.destroy(); + await doc.destroy(); return numPages; }); } diff --git a/x-pack/plugins/search_notebooks/server/lib/notebook_catalog.test.ts b/x-pack/plugins/search_notebooks/server/lib/notebook_catalog.test.ts index 13e79c4ed3422..0c6e4874b4bf1 100644 --- a/x-pack/plugins/search_notebooks/server/lib/notebook_catalog.test.ts +++ b/x-pack/plugins/search_notebooks/server/lib/notebook_catalog.test.ts @@ -25,24 +25,24 @@ describe('getNotebook', () => { jest.clearAllMocks(); }); - it('throws an error if given an unknown notebook id', () => { - expect(getNotebook('some-fake-id', options)).rejects.toThrow('Unknown Notebook ID'); + it('throws an error if given an unknown notebook id', async () => { + await expect(getNotebook('some-fake-id', options)).rejects.toThrow('Unknown Notebook ID'); expect(mockLogger.warn).toHaveBeenCalledTimes(1); }); - it('throws an error if the file is not found', () => { + it('throws an error if the file is not found', async () => { const notebookId = DEFAULT_NOTEBOOKS.notebooks[0].id; jest.mocked(fs.access).mockReset().mockRejectedValue(new Error('Boom')); - expect(getNotebook(notebookId, options)).rejects.toThrow('Failed to fetch notebook.'); + await expect(getNotebook(notebookId, options)).rejects.toThrow('Failed to fetch notebook.'); }); - it('Reads notebook', () => { + it('Reads notebook', async () => { const notebookId = DEFAULT_NOTEBOOKS.notebooks[0].id; jest.mocked(fs.access).mockReset().mockResolvedValue(undefined); - expect(getNotebook(notebookId, options)).resolves.toMatchObject({ + await expect(getNotebook(notebookId, options)).resolves.toMatchObject({ cells: expect.anything(), metadata: expect.anything(), }); diff --git a/x-pack/plugins/search_playground/server/lib/conversational_chain.test.ts b/x-pack/plugins/search_playground/server/lib/conversational_chain.test.ts index bb65f55928bcd..58ce10a3b8051 100644 --- a/x-pack/plugins/search_playground/server/lib/conversational_chain.test.ts +++ b/x-pack/plugins/search_playground/server/lib/conversational_chain.test.ts @@ -76,7 +76,7 @@ describe('conversational chain', () => { const stream = await conversationalChain.stream(aiClient, chat); - const streamToValue: string[] = await new Promise((resolve) => { + const streamToValue: string[] = await new Promise((resolve, reject) => { const reader = stream.getReader(); const textDecoder = new TextDecoder(); const chunks: string[] = []; @@ -89,7 +89,7 @@ describe('conversational chain', () => { chunks.push(textDecoder.decode(value)); read(); } - }); + }, reject); }; read(); }); diff --git a/x-pack/plugins/search_playground/server/lib/conversational_chain.ts b/x-pack/plugins/search_playground/server/lib/conversational_chain.ts index 0844fe3b64c42..b18faa06780e8 100644 --- a/x-pack/plugins/search_playground/server/lib/conversational_chain.ts +++ b/x-pack/plugins/search_playground/server/lib/conversational_chain.ts @@ -167,7 +167,7 @@ class ConversationalChainFn { // check that main chain (without parent) is finished: if (parentRunId == null) { - data.close(); + data.close().catch(() => {}); } }, }, diff --git a/x-pack/plugins/search_playground/server/routes.ts b/x-pack/plugins/search_playground/server/routes.ts index e9f40d89d18fe..d2081dade0474 100644 --- a/x-pack/plugins/search_playground/server/routes.ts +++ b/x-pack/plugins/search_playground/server/routes.ts @@ -147,15 +147,18 @@ export function defineRoutes({ const reader = (stream as ReadableStream).getReader(); const textDecoder = new TextDecoder(); - async function pushStreamUpdate() { - reader.read().then(({ done, value }: { done: boolean; value?: Uint8Array }) => { - if (done) { - end(); - return; - } - push(textDecoder.decode(value)); - pushStreamUpdate(); - }); + function pushStreamUpdate() { + reader + .read() + .then(({ done, value }: { done: boolean; value?: Uint8Array }) => { + if (done) { + end(); + return; + } + push(textDecoder.decode(value)); + pushStreamUpdate(); + }) + .catch(() => {}); } pushStreamUpdate(); diff --git a/x-pack/plugins/security/server/saved_objects/ensure_authorized.test.ts b/x-pack/plugins/security/server/saved_objects/ensure_authorized.test.ts index 22c219a5668ab..821a90dbdeb22 100644 --- a/x-pack/plugins/security/server/saved_objects/ensure_authorized.test.ts +++ b/x-pack/plugins/security/server/saved_objects/ensure_authorized.test.ts @@ -79,7 +79,7 @@ describe('ensureAuthorized', () => { test('throws an error when privilege check fails', async () => { const deps = setupDependencies(); deps.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue(new Error('Oh no!')); - expect(ensureAuthorized(deps, [], [], [])).rejects.toThrowError('Oh no!'); + await expect(ensureAuthorized(deps, [], [], [])).rejects.toThrowError('Oh no!'); }); describe('fully authorized', () => { @@ -149,7 +149,7 @@ describe('ensureAuthorized', () => { test('with default options', async () => { const deps = setupDependencies(); deps.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue(resolvedPrivileges); - expect( + await expect( ensureAuthorized(deps, types, actions, namespaces) ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unable to (bar a),(bar b),(bar c),(foo c)"`); }); @@ -199,7 +199,7 @@ describe('ensureAuthorized', () => { test('with default options', async () => { const deps = setupDependencies(); deps.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue(resolvedPrivileges); - expect( + await expect( ensureAuthorized(deps, types, actions, namespaces) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to (bar a),(bar b),(bar c),(foo a),(foo b),(foo c)"` diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts index a1988cb7a13ae..332b5778d67f7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts @@ -89,7 +89,7 @@ describe('Endpoint artifact packager task', () => { endpointAppContext: mockContext, taskManager: mockTaskManager, }); - manifestTaskInstance.start({ taskManager: taskManagerMock.createStart() }); + void manifestTaskInstance.start({ taskManager: taskManagerMock.createStart() }); mockContext.service.getManifestManager = jest.fn().mockReturnValue(manifestManager); diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task.ts b/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task.ts index a9c81fbd69e2c..8d77ddecbcf56 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task.ts @@ -40,7 +40,7 @@ export class CompleteExternalResponseActionsTask { private wasStarted = false; private log: Logger; private esClient: ElasticsearchClient | undefined = undefined; - private cleanup: (() => void | Promise) | undefined; + private cleanup: (() => void) | undefined; private taskTimeout = '20m'; // Default. Real value comes from server config private taskInterval = '60s'; // Default. Real value comes from server config @@ -54,7 +54,7 @@ export class CompleteExternalResponseActionsTask { return `${COMPLETE_EXTERNAL_RESPONSE_ACTIONS_TASK_TYPE}-${COMPLETE_EXTERNAL_RESPONSE_ACTIONS_TASK_VERSION}`; } - public async setup({ taskManager }: CompleteExternalResponseActionsTaskSetupOptions) { + public setup({ taskManager }: CompleteExternalResponseActionsTaskSetupOptions) { if (this.wasSetup) { throw new Error(`Task has already been setup!`); } @@ -143,7 +143,7 @@ export class CompleteExternalResponseActionsTask { this.log.info( `Un-registering task definition [${COMPLETE_EXTERNAL_RESPONSE_ACTIONS_TASK_TYPE}] (if it exists)` ); - taskManager.removeIfExists(COMPLETE_EXTERNAL_RESPONSE_ACTIONS_TASK_TYPE); + taskManager.removeIfExists(COMPLETE_EXTERNAL_RESPONSE_ACTIONS_TASK_TYPE).catch(() => {}); this.cleanup = undefined; }; } diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task_runner.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task_runner.test.ts index 14d93a292a573..9497f24c8fc42 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task_runner.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/complete_external_actions_task_runner.test.ts @@ -140,13 +140,13 @@ describe('CompleteExternalTaskRunner class', () => { return clientMock; } ); - runnerInstance.run(); + void runnerInstance.run(); await waitFor(() => { expect(endpointContextServicesMock.getInternalResponseActionsClient).toHaveBeenCalled(); }); - runnerInstance.cancel(); + await runnerInstance.cancel(); expect(processPendingActionsAbortSignal!.aborted).toBe(true); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts index 01d3ad006405f..13145db5e3e8e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts @@ -17,19 +17,28 @@ import { handleTree } from './resolver/tree/handler'; import { handleEntities } from './resolver/entity/handler'; import { handleEvents } from './resolver/events'; -export const registerResolverRoutes = async ( +export const registerResolverRoutes = ( router: SecuritySolutionPluginRouter, startServices: StartServicesAccessor, config: ConfigType ) => { - const [, { ruleRegistry, licensing }] = await startServices(); + const getRuleRegistry = async () => { + const [, { ruleRegistry }] = await startServices(); + return ruleRegistry; + }; + + const getLicensing = async () => { + const [, { licensing }] = await startServices(); + return licensing; + }; + router.post( { path: '/api/endpoint/resolver/tree', validate: validateTree, options: { authRequired: true }, }, - handleTree(ruleRegistry, config, licensing) + handleTree(getRuleRegistry, config, getLicensing) ); router.post( @@ -38,7 +47,7 @@ export const registerResolverRoutes = async ( validate: validateEvents, options: { authRequired: true }, }, - handleEvents(ruleRegistry) + handleEvents(getRuleRegistry) ); /** diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts index ddc961e369168..7d6e4865c9160 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts @@ -32,7 +32,7 @@ function createEvents( * requested. */ export function handleEvents( - ruleRegistry: RuleRegistryPluginStartContract + getRuleRegistry: () => Promise ): RequestHandler< unknown, TypeOf, @@ -44,6 +44,7 @@ export function handleEvents( body, } = req; const eventsClient = (await context.core).elasticsearch.client; + const ruleRegistry = await getRuleRegistry(); const alertsClient = await ruleRegistry.getRacClientWithRequest(req); const shouldExcludeColdAndFrozenTiers = await ( await context.core diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/handler.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/handler.ts index 48c99cd8ed112..3a3fb1d17816a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/handler.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/handler.ts @@ -19,15 +19,16 @@ import { featureUsageService } from '../../../services/feature_usage'; import { Fetcher } from './utils/fetch'; export function handleTree( - ruleRegistry: RuleRegistryPluginStartContract, + getRuleRegistry: () => Promise, config: ConfigType, - licensing: LicensingPluginStart + getLicensing: () => Promise ): RequestHandler> { return async (context, req, res) => { const client = (await context.core).elasticsearch.client; const { experimentalFeatures: { insightsRelatedAlertsByProcessAncestry }, } = config; + const licensing = await getLicensing(); const license = await firstValueFrom(licensing.license$); const hasAccessToInsightsRelatedByProcessAncestry = insightsRelatedAlertsByProcessAncestry && license.hasAtLeast('platinum'); @@ -40,7 +41,7 @@ export function handleTree( } const alertsClient = hasAccessToInsightsRelatedByProcessAncestry - ? await ruleRegistry.getRacClientWithRequest(req) + ? await (await getRuleRegistry()).getRacClientWithRequest(req) : undefined; const fetcher = new Fetcher(client, alertsClient); const body = await fetcher.tree({ ...req.body, shouldExcludeColdAndFrozenTiers }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/unified_manifest_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/unified_manifest_client.ts index ae1acdbd8e4cf..db47c43b68607 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/unified_manifest_client.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/unified_manifest_client.ts @@ -98,11 +98,7 @@ export class UnifiedManifestClient { const unifiedManifestsFetcher = this.fetchAllUnifiedManifests(this.savedObjectsClient, options); for await (const unifiedManifests of unifiedManifestsFetcher) { - if (cb.constructor.name === 'AsyncFunction') { - await cb(unifiedManifests); - } else { - cb(unifiedManifests); - } + await cb(unifiedManifests); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts b/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts index 05bd638956f89..202683c8d4c97 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts @@ -135,7 +135,7 @@ export class QueueProcessor { public addToQueue(...data: T[]) { if (data.length > 0) { this.queue.push(...data); - this.processQueue(); + this.processQueue().catch(() => {}); } } diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 34a3b44b551d6..7dddfa32a1967 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -572,7 +572,7 @@ describe('ingest_integration tests ', () => { const validDateYesterday = moment.utc().subtract(1, 'day'); - it('should throw if endpointProtectionUpdates productFeature is disabled and user modifies global_manifest_version', () => { + it('should throw if endpointProtectionUpdates productFeature is disabled and user modifies global_manifest_version', async () => { productFeaturesService = createProductFeaturesServiceMock( ALL_PRODUCT_FEATURE_KEYS.filter((key) => key !== 'endpoint_protection_updates') ); @@ -587,7 +587,7 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value.global_manifest_version = '2023-01-01'; - expect(() => + await expect(() => callback(policyConfig, soClient, esClient, requestContextMock.convertContext(ctx), req) ).rejects.toThrow( 'To modify protection updates, you must add at least Endpoint Complete to your project.' diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts index 99035d3b66a88..4e5a1e2f44ff2 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts @@ -223,7 +223,7 @@ export const getPackagePolicyUpdateCallback = ( validateEndpointPackagePolicy(endpointIntegrationData.inputs); - notifyProtectionFeatureUsage( + await notifyProtectionFeatureUsage( endpointIntegrationData, featureUsageService, endpointMetadataService @@ -294,7 +294,9 @@ export const getPackagePolicyPostCreateCallback = ( exceptionsClient, integrationConfig.value.eventFilters, packagePolicy - ); + ).catch((error) => { + logger.error(`Failed to create event filters: ${error}`); + }); } return packagePolicy; }; diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_event_filters.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_event_filters.ts index d9bab942de2ae..5e5cefd5d2a90 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_event_filters.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_event_filters.ts @@ -55,19 +55,19 @@ export const createEventFilters = async ( } } - createNonInteractiveSessionEventFilter(logger, exceptionsClient, packagePolicy); + await createNonInteractiveSessionEventFilter(logger, exceptionsClient, packagePolicy); }; /** * Create an Event Filter for non-interactive sessions and attach it to the policy */ -export const createNonInteractiveSessionEventFilter = ( +export const createNonInteractiveSessionEventFilter = async ( logger: Logger, exceptionsClient: ExceptionListClient, packagePolicy: PackagePolicy -): void => { +): Promise => { try { - exceptionsClient.createExceptionListItem({ + await exceptionsClient.createExceptionListItem({ listId: ENDPOINT_EVENT_FILTERS_LIST_ID, description: i18n.translate( 'xpack.securitySolution.fleetIntegration.elasticDefend.eventFilter.nonInteractiveSessions.description', diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_protection_updates_note.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_protection_updates_note.ts index 9106eba06e780..13ddda419ff90 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_protection_updates_note.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_protection_updates_note.ts @@ -23,11 +23,8 @@ export const removeProtectionUpdatesNote = async ( id: policy.id, }, }); - await pMap( - foundProtectionUpdatesNotes.saved_objects, - (protectionUpdatesNote: { id: string }) => { - soClient.delete(protectionUpdatesNoteSavedObjectType, protectionUpdatesNote.id); - } + await pMap(foundProtectionUpdatesNotes.saved_objects, (protectionUpdatesNote: { id: string }) => + soClient.delete(protectionUpdatesNoteSavedObjectType, protectionUpdatesNote.id) ); } }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts index 61bea17db1156..2a8705d03b877 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts @@ -19,8 +19,8 @@ describe('legacy_create_rule_actions_saved_object', () => { savedObjectsClient = savedObjectsClientMock.create(); }); - test('it creates a rule actions saved object with empty actions array', () => { - legacyCreateRuleActionsSavedObject({ + test('it creates a rule actions saved object with empty actions array', async () => { + await legacyCreateRuleActionsSavedObject({ ruleAlertId: '123', savedObjectsClient, actions: [], @@ -43,8 +43,8 @@ describe('legacy_create_rule_actions_saved_object', () => { }); }); - test('it creates a rule actions saved object with 1 single action', () => { - legacyCreateRuleActionsSavedObject({ + test('it creates a rule actions saved object with 1 single action', async () => { + await legacyCreateRuleActionsSavedObject({ ruleAlertId: '123', savedObjectsClient, actions: [ @@ -90,8 +90,8 @@ describe('legacy_create_rule_actions_saved_object', () => { }); }); - test('it creates a rule actions saved object with 2 actions', () => { - legacyCreateRuleActionsSavedObject({ + test('it creates a rule actions saved object with 2 actions', async () => { + await legacyCreateRuleActionsSavedObject({ ruleAlertId: '123', savedObjectsClient, actions: [ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts index 1f598f0ccf78b..ae3e21881d7af 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts @@ -33,8 +33,8 @@ describe('legacy_get_rule_actions_saved_object', () => { }); }); - test('calls "savedObjectsClient.find" with the expected "hasReferences"', () => { - legacyGetRuleActionsSavedObject({ ruleAlertId: '123', savedObjectsClient, logger }); + test('calls "savedObjectsClient.find" with the expected "hasReferences"', async () => { + await legacyGetRuleActionsSavedObject({ ruleAlertId: '123', savedObjectsClient, logger }); const [[arg1]] = savedObjectsClient.find.mock.calls; expect(arg1).toEqual({ hasReference: { id: '123', type: 'alert' }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts index 7a3fd49dcd2d1..5cbaa44834302 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts @@ -69,7 +69,7 @@ import { wrapSearchSourceClient } from './wrap_search_source_client'; const PREVIEW_TIMEOUT_SECONDS = 60; const MAX_ROUTE_CONCURRENCY = 10; -export const previewRulesRoute = async ( +export const previewRulesRoute = ( router: SecuritySolutionPluginRouter, config: ConfigType, ml: SetupPlugins['ml'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.test.ts index 67457b1574000..6fac2725754d5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.test.ts @@ -96,7 +96,7 @@ describe('ScheduleNotificationResponseActions', () => { }, }, ]; - scheduleNotificationResponseActions({ signals, responseActions }); + await scheduleNotificationResponseActions({ signals, responseActions }); expect(osqueryActionMock.create).toHaveBeenCalledWith({ ...defaultQueryResultParams, @@ -123,7 +123,7 @@ describe('ScheduleNotificationResponseActions', () => { }, }, ]; - scheduleNotificationResponseActions({ signals, responseActions }); + await scheduleNotificationResponseActions({ signals, responseActions }); expect(osqueryActionMock.create).toHaveBeenCalledWith({ ...defaultPackResultParams, @@ -149,7 +149,7 @@ describe('ScheduleNotificationResponseActions', () => { }, }, ]; - scheduleNotificationResponseActions({ signals, responseActions }); + await scheduleNotificationResponseActions({ signals, responseActions }); expect(endpointActionMock.getInternalResponseActionsClient).toHaveBeenCalledTimes(1); expect(endpointActionMock.getInternalResponseActionsClient).toHaveBeenCalledWith({ @@ -188,7 +188,7 @@ describe('ScheduleNotificationResponseActions', () => { }, }, ]; - scheduleNotificationResponseActions({ + await scheduleNotificationResponseActions({ signals, responseActions, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.ts index 93c8e22ac2316..d20995291b5f1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_response_actions/schedule_notification_response_actions.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { each } from 'lodash'; import type { EndpointAppContextService } from '../../../endpoint/endpoint_app_context_services'; import type { SetupPlugins } from '../../../plugin_contract'; import { ResponseActionTypesEnum } from '../../../../common/api/detection_engine/model/rule_response_actions'; @@ -24,22 +23,24 @@ export const getScheduleNotificationResponseActionsService = osqueryCreateActionService, endpointAppContextService, }: ScheduleNotificationResponseActionsService) => - ({ signals, responseActions }: ScheduleNotificationActions) => { + async ({ signals, responseActions }: ScheduleNotificationActions) => { const alerts = (signals as Alert[]).filter((alert) => alert.agent?.id) as AlertWithAgent[]; - each(responseActions, (responseAction) => { - if ( - responseAction.actionTypeId === ResponseActionTypesEnum['.osquery'] && - osqueryCreateActionService - ) { - osqueryResponseAction(responseAction, osqueryCreateActionService, { - alerts, - }); - } - if (responseAction.actionTypeId === ResponseActionTypesEnum['.endpoint']) { - endpointResponseAction(responseAction, endpointAppContextService, { - alerts, - }); - } - }); + await Promise.all( + responseActions.map(async (responseAction) => { + if ( + responseAction.actionTypeId === ResponseActionTypesEnum['.osquery'] && + osqueryCreateActionService + ) { + await osqueryResponseAction(responseAction, osqueryCreateActionService, { + alerts, + }); + } + if (responseAction.actionTypeId === ResponseActionTypesEnum['.endpoint']) { + await endpointResponseAction(responseAction, endpointAppContextService, { + alerts, + }); + } + }) + ); }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/asset_criticality_data_client.test.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/asset_criticality_data_client.test.ts index b77ea7742077d..9cbb6ee9ce2e5 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/asset_criticality_data_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/asset_criticality_data_client.test.ts @@ -81,7 +81,7 @@ describe('AssetCriticalityDataClient', () => { }); it('searches in the asset criticality index', async () => { - subject.search({ query: { match_all: {} } }); + await subject.search({ query: { match_all: {} } }); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ index: '.asset-criticality.asset-criticality-default' }) @@ -89,7 +89,7 @@ describe('AssetCriticalityDataClient', () => { }); it('requires a query parameter', async () => { - subject.search({ query: { match_all: {} } }); + await subject.search({ query: { match_all: {} } }); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ body: { query: { match_all: {} } } }) @@ -97,13 +97,13 @@ describe('AssetCriticalityDataClient', () => { }); it('accepts a size parameter', async () => { - subject.search({ query: { match_all: {} }, size: 100 }); + await subject.search({ query: { match_all: {} }, size: 100 }); expect(esClientMock.search).toHaveBeenCalledWith(expect.objectContaining({ size: 100 })); }); it('defaults to the default query size', async () => { - subject.search({ query: { match_all: {} } }); + await subject.search({ query: { match_all: {} } }); const defaultSize = 1_000; expect(esClientMock.search).toHaveBeenCalledWith( @@ -112,14 +112,14 @@ describe('AssetCriticalityDataClient', () => { }); it('caps the size to the maximum query size', async () => { - subject.search({ query: { match_all: {} }, size: 999999 }); + await subject.search({ query: { match_all: {} }, size: 999999 }); const maxSize = 100_000; expect(esClientMock.search).toHaveBeenCalledWith(expect.objectContaining({ size: maxSize })); }); it('ignores an index_not_found_exception if the criticality index does not exist', async () => { - subject.search({ query: { match_all: {} } }); + await subject.search({ query: { match_all: {} } }); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ ignore_unavailable: true }) diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/tasks/risk_scoring_task.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/tasks/risk_scoring_task.ts index f936ca6a83c76..b3d25855ba427 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/tasks/risk_scoring_task.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/tasks/risk_scoring_task.ts @@ -310,7 +310,7 @@ export const runTask = async ({ }; telemetry.reportEvent(RISK_SCORE_EXECUTION_SUCCESS_EVENT.eventType, telemetryEvent); - riskScoreService.scheduleLatestTransformNow(); + await riskScoreService.scheduleLatestTransformNow(); if (isCancelled()) { log('task was cancelled'); diff --git a/x-pack/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts b/x-pack/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts index 3597a109adbfe..b59dafb2f0eb7 100644 --- a/x-pack/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts +++ b/x-pack/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts @@ -192,7 +192,7 @@ describe('ProductFeaturesService', () => { expect(mockHttpSetup.registerOnPostAuth).toHaveBeenCalledTimes(1); }); - it('should authorize when no tag matches', () => { + it('should authorize when no tag matches', async () => { const experimentalFeatures = {} as ExperimentalFeatures; const productFeaturesService = new ProductFeaturesService( loggerMock.create(), @@ -200,14 +200,14 @@ describe('ProductFeaturesService', () => { ); productFeaturesService.registerApiAccessControl(mockHttpSetup); - lastRegisteredFn(getReq(['access:something', 'access:securitySolution']), res, toolkit); + await lastRegisteredFn(getReq(['access:something', 'access:securitySolution']), res, toolkit); expect(MockedProductFeatures.mock.instances[0].isActionRegistered).not.toHaveBeenCalled(); expect(res.notFound).not.toHaveBeenCalled(); expect(toolkit.next).toHaveBeenCalledTimes(1); }); - it('should check when tag matches and return not found when not action registered', () => { + it('should check when tag matches and return not found when not action registered', async () => { const experimentalFeatures = {} as ExperimentalFeatures; const productFeaturesService = new ProductFeaturesService( loggerMock.create(), @@ -218,7 +218,7 @@ describe('ProductFeaturesService', () => { (MockedProductFeatures.mock.instances[0].isActionRegistered as jest.Mock).mockReturnValueOnce( false ); - lastRegisteredFn(getReq(['access:securitySolution-foo']), res, toolkit); + await lastRegisteredFn(getReq(['access:securitySolution-foo']), res, toolkit); expect(MockedProductFeatures.mock.instances[0].isActionRegistered).toHaveBeenCalledWith( 'api:securitySolution-foo' @@ -227,7 +227,7 @@ describe('ProductFeaturesService', () => { expect(toolkit.next).not.toHaveBeenCalled(); }); - it('should check when tag matches and continue when action registered', () => { + it('should check when tag matches and continue when action registered', async () => { const experimentalFeatures = {} as ExperimentalFeatures; const productFeaturesService = new ProductFeaturesService( loggerMock.create(), @@ -238,7 +238,7 @@ describe('ProductFeaturesService', () => { (MockedProductFeatures.mock.instances[0].isActionRegistered as jest.Mock).mockReturnValueOnce( true ); - lastRegisteredFn(getReq(['access:securitySolution-foo']), res, toolkit); + await lastRegisteredFn(getReq(['access:securitySolution-foo']), res, toolkit); expect(MockedProductFeatures.mock.instances[0].isActionRegistered).toHaveBeenCalledWith( 'api:securitySolution-foo' @@ -247,7 +247,7 @@ describe('ProductFeaturesService', () => { expect(toolkit.next).toHaveBeenCalledTimes(1); }); - it('should check when productFeature tag when it matches and return not found when not enabled', () => { + it('should check when productFeature tag when it matches and return not found when not enabled', async () => { const experimentalFeatures = {} as ExperimentalFeatures; const productFeaturesService = new ProductFeaturesService( loggerMock.create(), @@ -257,14 +257,14 @@ describe('ProductFeaturesService', () => { productFeaturesService.isEnabled = jest.fn().mockReturnValueOnce(false); - lastRegisteredFn(getReq(['securitySolutionProductFeature:foo']), res, toolkit); + await lastRegisteredFn(getReq(['securitySolutionProductFeature:foo']), res, toolkit); expect(productFeaturesService.isEnabled).toHaveBeenCalledWith('foo'); expect(res.notFound).toHaveBeenCalledTimes(1); expect(toolkit.next).not.toHaveBeenCalled(); }); - it('should check when productFeature tag when it matches and continue when enabled', () => { + it('should check when productFeature tag when it matches and continue when enabled', async () => { const experimentalFeatures = {} as ExperimentalFeatures; const productFeaturesService = new ProductFeaturesService( loggerMock.create(), @@ -274,7 +274,7 @@ describe('ProductFeaturesService', () => { productFeaturesService.isEnabled = jest.fn().mockReturnValueOnce(true); - lastRegisteredFn(getReq(['securitySolutionProductFeature:foo']), res, toolkit); + await lastRegisteredFn(getReq(['securitySolutionProductFeature:foo']), res, toolkit); expect(productFeaturesService.isEnabled).toHaveBeenCalledWith('foo'); expect(res.notFound).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts index eff642239da3a..5b59282a320ea 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts @@ -596,7 +596,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { yield alerts; } - this.closePointInTime(pitId); + await this.closePointInTime(pitId); } public async fetchPolicyConfigs(id: string) { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts index a788a59b63b71..0f21cb58824f6 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts @@ -18,6 +18,7 @@ import type { TaskManagerSetupContract, TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; +import { exhaustMap, Subject, takeUntil, timer } from 'rxjs'; import type { ITelemetryReceiver } from './receiver'; import { copyAllowlistedFields, filterList } from './filterlists'; import { createTelemetryTaskConfigs } from './tasks'; @@ -92,10 +93,10 @@ export class TelemetryEventsSender implements ITelemetryEventsSender { private readonly initialCheckDelayMs = 10 * 1000; private readonly checkIntervalMs = 60 * 1000; private readonly logger: Logger; + private readonly stop$ = new Subject(); private maxQueueSize = telemetryConfiguration.telemetry_max_buffer_size; private telemetryStart?: TelemetryPluginStart; private telemetrySetup?: TelemetryPluginSetup; - private intervalId?: NodeJS.Timeout; private isSending = false; private receiver: ITelemetryReceiver | undefined; private queue: TelemetryEvent[] = []; @@ -162,16 +163,16 @@ export class TelemetryEventsSender implements ITelemetryEventsSender { } tlog(this.logger, `Starting local task`); - setTimeout(() => { - this.sendIfDue(); - this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); - }, this.initialCheckDelayMs); + timer(this.initialCheckDelayMs, this.checkIntervalMs) + .pipe( + takeUntil(this.stop$), + exhaustMap(() => this.sendIfDue()) + ) + .subscribe(); } public stop() { - if (this.intervalId) { - clearInterval(this.intervalId); - } + this.stop$.next(); } public queueTelemetryEvents(events: TelemetryEvent[]) { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/task_metrics.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/task_metrics.test.ts index 784c34bf11d7d..866bd7cd1ba0c 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/task_metrics.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/task_metrics.test.ts @@ -35,7 +35,7 @@ describe('task metrics', () => { }); it('should record passed task metrics', async () => { - const metric = sendMetric('test'); + const metric = await sendMetric('test'); expect(metric.name).toEqual('test'); expect(metric.passed).toBeTruthy(); @@ -49,7 +49,7 @@ describe('task metrics', () => { jest.spyOn(telemetryConfiguration, 'use_async_sender', 'get').mockReturnValue(false); const trace = taskMetricsService.start('test'); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); expect(mockTelemetryEventsSender.sendAsync).toHaveBeenCalledTimes(0); expect(mockTelemetryEventsSender.sendAsync).toHaveBeenCalledTimes(0); @@ -57,7 +57,7 @@ describe('task metrics', () => { }); it('should record failed task metrics', async () => { - const metric = sendMetric('test', Error('Boom!')); + const metric = await sendMetric('test', Error('Boom!')); expect(metric.name).toEqual('test'); expect(metric.passed).toBeFalsy(); @@ -67,9 +67,9 @@ describe('task metrics', () => { expect(metric.end_time).toBeGreaterThan(0); }); - function sendMetric(name: string, error?: Error): TaskMetric { + async function sendMetric(name: string, error?: Error): Promise { const trace = taskMetricsService.start(name); - taskMetricsService.end(trace, error); + await taskMetricsService.end(trace, error); expect(mockTelemetryEventsSender.sendAsync).toHaveBeenCalledTimes(1); const events = mockTelemetryEventsSender.sendAsync.mock.calls[0][1]; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts index 701f42a89f4c0..0c95ccf651013 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts @@ -45,7 +45,7 @@ export function createTelemetryConfigurationTaskConfig() { if (manifest.notModified) { log.l('No new configuration artifact found, skipping...'); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } @@ -106,14 +106,14 @@ export function createTelemetryConfigurationTaskConfig() { _receiver.setNumDocsToSample(configArtifact.pagination_config.num_docs_to_sample); } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); log.l(`Updated TelemetryConfiguration: ${JSON.stringify(telemetryConfiguration)}`); return 0; } catch (err) { log.l(`Failed to set telemetry configuration due to ${err.message}`); telemetryConfiguration.resetAllToDefault(); - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts index f7616830716f1..91a2bf2a5b85a 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts @@ -62,7 +62,7 @@ export function createTelemetryDetectionRuleListsTaskConfig(maxTelemetryBatch: n if (!prebuiltRules) { log.l('no prebuilt rules found'); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } @@ -118,7 +118,7 @@ export function createTelemetryDetectionRuleListsTaskConfig(maxTelemetryBatch: n for (const batch of batches) { await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); log.l( `Task: ${taskId} executed. Processed ${detectionRuleExceptionsJson.length} exceptions` @@ -126,7 +126,7 @@ export function createTelemetryDetectionRuleListsTaskConfig(maxTelemetryBatch: n return detectionRuleExceptionsJson.length; } catch (err) { - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts index 85ac4d744feae..1c691aea4155f 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts @@ -58,7 +58,7 @@ export function createTelemetryDiagnosticsTaskConfig() { if (alerts.length === 0) { log.l('no diagnostic alerts retrieved'); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return alertCount; } @@ -67,10 +67,10 @@ export function createTelemetryDiagnosticsTaskConfig() { await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_ALERTS, processedAlerts); } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return alertCount; } catch (err) { - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts index a55cbb4eda19a..aceb3ebf98926 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts @@ -94,14 +94,14 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, batch); } } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return documents.length; } catch (err) { log.l(`Error running endpoint alert telemetry task`, { error: JSON.stringify(err), }); - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts index 5a869ecade992..69a3ee646f0cf 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts @@ -44,7 +44,7 @@ export function createTelemetryFilterListArtifactTaskConfig() { const manifest = await artifactService.getArtifact(artifactName); if (manifest.notModified) { log.l('No new filterlist artifact found, skipping...'); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } @@ -53,12 +53,12 @@ export function createTelemetryFilterListArtifactTaskConfig() { filterList.endpointAlerts = artifact.endpoint_alerts; filterList.exceptionLists = artifact.exception_lists; filterList.prebuiltRulesAlerts = artifact.prebuilt_rules_alerts; - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } catch (err) { log.l(`Failed to set telemetry filterlist artifact due to ${err.message}`); filterList.resetAllToDefault(); - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts index 921ff422bded5..3fda2878d4566 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts @@ -62,7 +62,7 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n if (index === undefined) { log.l(`alerts index is not ready yet, skipping telemetry task`); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } @@ -71,7 +71,7 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n taskExecutionPeriod.current )) { if (alerts.length === 0) { - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } @@ -100,17 +100,17 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n const batches = batchTelemetryRecords(enrichedAlerts, maxTelemetryBatch); const promises = batches.map(async (batch) => { - sender.sendOnDemand(TELEMETRY_CHANNEL_DETECTION_ALERTS, batch); + await sender.sendOnDemand(TELEMETRY_CHANNEL_DETECTION_ALERTS, batch); }); await Promise.all(promises); } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return 0; } catch (err) { logger.error('could not complete prebuilt alerts telemetry task'); - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts index cc51fa7ba6d5b..09e1d14558c54 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts @@ -158,10 +158,10 @@ export function createTelemetrySecurityListTaskConfig(maxTelemetryBatch: number) if (valueListMetaData?.total_list_count) { await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, [valueListMetaData]); } - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return trustedApplicationsCount + endpointExceptionsCount + endpointEventFiltersCount; } catch (err) { - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts index fa0a280fb7026..c016f029fa2a5 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts @@ -67,7 +67,7 @@ export function createTelemetryTimelineTaskConfig() { }); if (result.timeline) { - sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [result.timeline]); + await sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [result.timeline]); counter += 1; } else { log.l('no events in timeline'); @@ -76,11 +76,11 @@ export function createTelemetryTimelineTaskConfig() { log.l(`sent ${counter} timelines. Concluding timeline task.`); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return counter; } catch (err) { - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines_diagnostic.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines_diagnostic.ts index 9207adf7ae748..31718ec47b1e6 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines_diagnostic.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines_diagnostic.ts @@ -67,7 +67,7 @@ export function createTelemetryDiagnosticTimelineTaskConfig() { }); if (result.timeline) { - sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [result.timeline]); + await sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [result.timeline]); counter += 1; } else { log.l('no events in timeline'); @@ -76,11 +76,11 @@ export function createTelemetryDiagnosticTimelineTaskConfig() { log.l(`sent ${counter} timelines. Concluding timeline task.`); - taskMetricsService.end(trace); + await taskMetricsService.end(trace); return counter; } catch (err) { - taskMetricsService.end(trace, err); + await taskMetricsService.end(trace, err); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/copy_timeline/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/copy_timeline/index.ts index 3a55b4fef8086..0e288e0099596 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/copy_timeline/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/copy_timeline/index.ts @@ -17,7 +17,7 @@ import { buildSiemResponse } from '../../../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../../utils/common'; -export const copyTimelineRoute = async ( +export const copyTimelineRoute = ( router: SecuritySolutionPluginRouter, _: ConfigType, security: SetupPlugins['security'] diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 998e02aba56ad..b0eb25bd3c18f 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -409,74 +409,80 @@ export class Plugin implements ISecuritySolutionPlugin { this.completeExternalResponseActionsTask.setup({ taskManager: plugins.taskManager }); } - core.getStartServices().then(([_, depsStart]) => { - appClientFactory.setup({ - getSpaceId: depsStart.spaces?.spacesService?.getSpaceId, - config, - kibanaVersion: pluginContext.env.packageInfo.version, - kibanaBranch: pluginContext.env.packageInfo.branch, - }); + core + .getStartServices() + .then(async ([_, depsStart]) => { + appClientFactory.setup({ + getSpaceId: depsStart.spaces?.spacesService?.getSpaceId, + config, + kibanaVersion: pluginContext.env.packageInfo.version, + kibanaBranch: pluginContext.env.packageInfo.branch, + }); + + const endpointFieldsStrategy = endpointFieldsProvider( + this.endpointAppContextService, + depsStart.data.indexPatterns + ); + plugins.data.search.registerSearchStrategy( + ENDPOINT_FIELDS_SEARCH_STRATEGY, + endpointFieldsStrategy + ); - const endpointFieldsStrategy = endpointFieldsProvider( - this.endpointAppContextService, - depsStart.data.indexPatterns - ); - plugins.data.search.registerSearchStrategy( - ENDPOINT_FIELDS_SEARCH_STRATEGY, - endpointFieldsStrategy - ); + const endpointPackagePoliciesStatsStrategy = + endpointPackagePoliciesStatsSearchStrategyProvider(this.endpointAppContextService); + plugins.data.search.registerSearchStrategy( + ENDPOINT_PACKAGE_POLICIES_STATS_STRATEGY, + endpointPackagePoliciesStatsStrategy + ); - const endpointPackagePoliciesStatsStrategy = - endpointPackagePoliciesStatsSearchStrategyProvider(this.endpointAppContextService); - plugins.data.search.registerSearchStrategy( - ENDPOINT_PACKAGE_POLICIES_STATS_STRATEGY, - endpointPackagePoliciesStatsStrategy - ); + const securitySolutionSearchStrategy = securitySolutionSearchStrategyProvider( + depsStart.data, + this.endpointContext, + depsStart.spaces?.spacesService?.getSpaceId, + ruleDataClient + ); - const securitySolutionSearchStrategy = securitySolutionSearchStrategyProvider( - depsStart.data, - this.endpointContext, - depsStart.spaces?.spacesService?.getSpaceId, - ruleDataClient - ); + plugins.data.search.registerSearchStrategy( + 'securitySolutionSearchStrategy', + securitySolutionSearchStrategy + ); + const endpointSearchStrategy = endpointSearchStrategyProvider( + depsStart.data, + this.endpointContext + ); - plugins.data.search.registerSearchStrategy( - 'securitySolutionSearchStrategy', - securitySolutionSearchStrategy - ); - const endpointSearchStrategy = endpointSearchStrategyProvider( - depsStart.data, - this.endpointContext - ); + plugins.data.search.registerSearchStrategy( + ENDPOINT_SEARCH_STRATEGY, + endpointSearchStrategy + ); - plugins.data.search.registerSearchStrategy(ENDPOINT_SEARCH_STRATEGY, endpointSearchStrategy); - - /** - * Register a config for the security guide - */ - if (depsStart.cloudExperiments && i18n.getLocale() === 'en') { - try { - depsStart.cloudExperiments - .getVariation('security-solutions.guided-onboarding-content', defaultGuideTranslations) - .then((variation) => { - plugins.guidedOnboarding?.registerGuideConfig( - siemGuideId, - getSiemGuideConfig(variation) - ); - }); - } catch { + /** + * Register a config for the security guide + */ + if (depsStart.cloudExperiments && i18n.getLocale() === 'en') { + try { + const variation = await depsStart.cloudExperiments.getVariation( + 'security-solutions.guided-onboarding-content', + defaultGuideTranslations + ); + plugins.guidedOnboarding?.registerGuideConfig( + siemGuideId, + getSiemGuideConfig(variation) + ); + } catch { + plugins.guidedOnboarding?.registerGuideConfig( + siemGuideId, + getSiemGuideConfig(defaultGuideTranslations) + ); + } + } else { plugins.guidedOnboarding?.registerGuideConfig( siemGuideId, getSiemGuideConfig(defaultGuideTranslations) ); } - } else { - plugins.guidedOnboarding?.registerGuideConfig( - siemGuideId, - getSiemGuideConfig(defaultGuideTranslations) - ); - } - }); + }) + .catch(() => {}); // it shouldn't reject, but just in case setIsElasticCloudDeployment(plugins.cloud.isCloudEnabled ?? false); @@ -586,29 +592,32 @@ export class Plugin implements ISecuritySolutionPlugin { }); // Migrate artifacts to fleet and then start the manifest task after that is done - plugins.fleet.fleetSetupCompleted().then(() => { - if (this.manifestTask) { - logger.info('Dependent plugin setup complete - Starting ManifestTask'); - this.manifestTask.start({ - taskManager, - }); - } else { - logger.error(new Error('User artifacts task not available.')); - } + plugins.fleet + .fleetSetupCompleted() + .then(async () => { + if (this.manifestTask) { + logger.info('Dependent plugin setup complete - Starting ManifestTask'); + await this.manifestTask.start({ + taskManager, + }); + } else { + logger.error(new Error('User artifacts task not available.')); + } - turnOffPolicyProtectionsIfNotSupported( - core.elasticsearch.client.asInternalUser, - endpointFleetServicesFactory.asInternalUser(), - productFeaturesService, - logger - ); + await turnOffPolicyProtectionsIfNotSupported( + core.elasticsearch.client.asInternalUser, + endpointFleetServicesFactory.asInternalUser(), + productFeaturesService, + logger + ); - turnOffAgentPolicyFeatures( - endpointFleetServicesFactory.asInternalUser(), - productFeaturesService, - logger - ); - }); + await turnOffAgentPolicyFeatures( + endpointFleetServicesFactory.asInternalUser(), + productFeaturesService, + logger + ); + }) + .catch(() => {}); // License related start licenseService.start(this.licensing$); @@ -653,22 +662,26 @@ export class Plugin implements ISecuritySolutionPlugin { }); if (plugins.taskManager) { - this.completeExternalResponseActionsTask.start({ - taskManager: plugins.taskManager, - esClient: core.elasticsearch.client.asInternalUser, - }); + this.completeExternalResponseActionsTask + .start({ + taskManager: plugins.taskManager, + esClient: core.elasticsearch.client.asInternalUser, + }) + .catch(() => {}); // it shouldn't refuse, but just in case } - this.telemetryReceiver.start( - core, - (type: string) => core.savedObjects.getIndexForType(type), - DEFAULT_ALERTS_INDEX, - this.endpointAppContextService, - exceptionListClient, - packageService - ); + this.telemetryReceiver + .start( + core, + (type: string) => core.savedObjects.getIndexForType(type), + DEFAULT_ALERTS_INDEX, + this.endpointAppContextService, + exceptionListClient, + packageService + ) + .catch(() => {}); - artifactService.start(this.telemetryReceiver); + artifactService.start(this.telemetryReceiver).catch(() => {}); this.asyncTelemetryEventsSender.start(plugins.telemetry); @@ -681,8 +694,8 @@ export class Plugin implements ISecuritySolutionPlugin { const endpointPkgInstallationPromise = this.endpointContext.service .getInternalFleetServices() .packages.getInstallation(FLEET_ENDPOINT_PACKAGE); - Promise.all([endpointPkgInstallationPromise, plugins.fleet?.fleetSetupCompleted()]).then( - ([endpointPkgInstallation]) => { + Promise.all([endpointPkgInstallationPromise, plugins.fleet?.fleetSetupCompleted()]) + .then(async ([endpointPkgInstallation]) => { if (plugins.taskManager) { if ( endpointPkgInstallation?.version && @@ -691,10 +704,10 @@ export class Plugin implements ISecuritySolutionPlugin { return; } - this.checkMetadataTransformsTask?.start({ taskManager: plugins.taskManager }); + await this.checkMetadataTransformsTask?.start({ taskManager: plugins.taskManager }); } - } - ); + }) + .catch(() => {}); // it shouldn't reject, but just in case if (registerIngestCallback) { registerIngestCallback( @@ -727,11 +740,11 @@ export class Plugin implements ISecuritySolutionPlugin { public stop() { this.logger.debug('Stopping plugin'); - this.asyncTelemetryEventsSender.stop(); + this.asyncTelemetryEventsSender.stop().catch(() => {}); this.telemetryEventsSender.stop(); this.endpointAppContextService.stop(); this.policyWatcher?.stop(); - this.completeExternalResponseActionsTask.stop(); + this.completeExternalResponseActionsTask.stop().catch(() => {}); licenseService.stop(); } } diff --git a/x-pack/plugins/security_solution/server/usage/queries/get_case_comments.ts b/x-pack/plugins/security_solution/server/usage/queries/get_case_comments.ts index 43acb1db00c1b..f74642507de34 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/get_case_comments.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/get_case_comments.ts @@ -50,7 +50,7 @@ export const getCaseComments = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/security_solution/server/usage/queries/get_detection_rules.ts b/x-pack/plugins/security_solution/server/usage/queries/get_detection_rules.ts index 3452a364503ce..ae0cb67e02423 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/get_detection_rules.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/get_detection_rules.ts @@ -74,7 +74,7 @@ export const getDetectionRules = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts b/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts index 9b7140d734d16..c4b795b608466 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts @@ -61,7 +61,7 @@ export const legacyGetRuleActions = async ({ } try { - finder.close(); + await finder.close(); } catch (exception) { // This is just a pre-caution in case the finder does a throw we don't want to blow up // the response. We have seen this within e2e test containers but nothing happen in normal diff --git a/x-pack/plugins/security_solution_serverless/server/plugin.ts b/x-pack/plugins/security_solution_serverless/server/plugin.ts index cc89c3ce76e09..2bf9e901a4a24 100644 --- a/x-pack/plugins/security_solution_serverless/server/plugin.ts +++ b/x-pack/plugins/security_solution_serverless/server/plugin.ts @@ -125,23 +125,27 @@ export class SecuritySolutionServerlessPlugin const internalESClient = coreStart.elasticsearch.client.asInternalUser; const internalSOClient = coreStart.savedObjects.createInternalRepository(); - this.cloudSecurityUsageReportingTask?.start({ - taskManager: pluginsSetup.taskManager, - interval: cloudSecurityMetringTaskProperties.interval, - }); - - this.endpointUsageReportingTask?.start({ - taskManager: pluginsSetup.taskManager, - interval: ENDPOINT_METERING_TASK.INTERVAL, - }); - - this.nlpCleanupTask?.start({ taskManager: pluginsSetup.taskManager }); + this.cloudSecurityUsageReportingTask + ?.start({ + taskManager: pluginsSetup.taskManager, + interval: cloudSecurityMetringTaskProperties.interval, + }) + .catch(() => {}); + + this.endpointUsageReportingTask + ?.start({ + taskManager: pluginsSetup.taskManager, + interval: ENDPOINT_METERING_TASK.INTERVAL, + }) + .catch(() => {}); + + this.nlpCleanupTask?.start({ taskManager: pluginsSetup.taskManager }).catch(() => {}); setEndpointPackagePolicyServerlessFlag( internalSOClient, internalESClient, pluginsSetup.fleet.packagePolicyService - ); + ).catch(() => {}); return {}; } diff --git a/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts index 88edecd4cfd9d..75bc95365bb04 100644 --- a/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts +++ b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts @@ -61,13 +61,13 @@ describe('fetch index lib function', () => { jest.clearAllMocks(); }); - it('should return index if all client calls succeed', () => { + it('should return index if all client calls succeed', async () => { mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); mockClient.indices.stats.mockResolvedValue(regularIndexStatsResponse); mockClient.count.mockResolvedValue(indexCountResponse); (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); - expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + await expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ index: { aliases: {}, count: 100, @@ -77,7 +77,7 @@ describe('fetch index lib function', () => { }); }); - it('should throw an error if get index rejects', () => { + it('should throw an error if get index rejects', async () => { const expectedError = new Error('Boom!'); mockClient.indices.get.mockRejectedValue(expectedError); @@ -85,10 +85,10 @@ describe('fetch index lib function', () => { mockClient.count.mockResolvedValue(indexCountResponse); (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); - expect(fetchIndex(client(), indexName)).rejects.toEqual(expectedError); + await expect(fetchIndex(client(), indexName)).rejects.toEqual(expectedError); }); - it('should return partial data if index stats rejects', () => { + it('should return partial data if index stats rejects', async () => { const expectedError = new Error('Boom!'); mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); @@ -96,7 +96,7 @@ describe('fetch index lib function', () => { mockClient.count.mockResolvedValue(indexCountResponse); (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); - expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + await expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ index: { aliases: {}, count: 100, @@ -105,7 +105,7 @@ describe('fetch index lib function', () => { }); }); - it('should return partial data if index count rejects', () => { + it('should return partial data if index count rejects', async () => { const expectedError = new Error('Boom!'); mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); @@ -113,7 +113,7 @@ describe('fetch index lib function', () => { mockClient.count.mockRejectedValue(expectedError); (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); - expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + await expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ index: { aliases: {}, count: 0, @@ -123,7 +123,7 @@ describe('fetch index lib function', () => { }); }); - it('should return partial data if fetch connector rejects', () => { + it('should return partial data if fetch connector rejects', async () => { const expectedError = new Error('Boom!'); mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); @@ -131,7 +131,7 @@ describe('fetch index lib function', () => { mockClient.count.mockResolvedValue(indexCountResponse); (fetchConnectorByIndexName as unknown as jest.Mock).mockRejectedValue(expectedError); - expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + await expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ index: { aliases: {}, count: 100, diff --git a/x-pack/plugins/serverless_search/server/plugin.ts b/x-pack/plugins/serverless_search/server/plugin.ts index a7b779a1239c7..0601b099d8a0d 100644 --- a/x-pack/plugins/serverless_search/server/plugin.ts +++ b/x-pack/plugins/serverless_search/server/plugin.ts @@ -34,7 +34,7 @@ export interface RouteDependencies { http: CoreSetup['http']; logger: Logger; router: IRouter; - security: SecurityPluginStart; + getSecurity: () => Promise; } export class ServerlessSearchPlugin @@ -49,7 +49,6 @@ export class ServerlessSearchPlugin // @ts-ignore config is not used for now private readonly config: ServerlessSearchConfig; private readonly logger: Logger; - private security?: SecurityPluginStart; constructor(initializerContext: PluginInitializerContext) { this.config = initializerContext.config.get(); @@ -82,25 +81,23 @@ export class ServerlessSearchPlugin { serverless, usageCollection }: SetupDependencies ) { const router = http.createRouter(); - getStartServices().then(([, { security }]) => { - this.security = security; - const dependencies = { - http, - logger: this.logger, - router, - security: this.security, - }; + const dependencies = { + http, + logger: this.logger, + router, + getSecurity: async () => { + const [, { security }] = await getStartServices(); + return security; + }, + }; - registerApiKeyRoutes(dependencies); - registerConnectorsRoutes(dependencies); - registerIndicesRoutes(dependencies); - registerMappingRoutes(dependencies); - }); + registerApiKeyRoutes(dependencies); + registerConnectorsRoutes(dependencies); + registerIndicesRoutes(dependencies); + registerMappingRoutes(dependencies); if (usageCollection) { - getStartServices().then(() => { - registerTelemetryUsageCollector(usageCollection, this.logger); - }); + registerTelemetryUsageCollector(usageCollection, this.logger); } serverless.setupProjectSettings(SEARCH_PROJECT_SETTINGS); @@ -108,7 +105,7 @@ export class ServerlessSearchPlugin } public start(core: CoreStart, { dataViews }: StartDependencies) { - this.createDefaultDataView(core, dataViews); + this.createDefaultDataView(core, dataViews).catch(() => {}); return {}; } diff --git a/x-pack/plugins/serverless_search/server/routes/api_key_routes.ts b/x-pack/plugins/serverless_search/server/routes/api_key_routes.ts index 9753420234208..397145ac647b2 100644 --- a/x-pack/plugins/serverless_search/server/routes/api_key_routes.ts +++ b/x-pack/plugins/serverless_search/server/routes/api_key_routes.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../plugin'; -export const registerApiKeyRoutes = ({ logger, router, security }: RouteDependencies) => { +export const registerApiKeyRoutes = ({ logger, router, getSecurity }: RouteDependencies) => { router.get( { path: '/internal/serverless_search/api_keys', @@ -16,6 +16,7 @@ export const registerApiKeyRoutes = ({ logger, router, security }: RouteDependen }, async (context, request, response) => { const { client } = (await context.core).elasticsearch; + const security = await getSecurity(); const user = security.authc.getCurrentUser(request); if (user) { const apiKeys = await client.asCurrentUser.security.getApiKey({ username: user.username }); @@ -37,6 +38,7 @@ export const registerApiKeyRoutes = ({ logger, router, security }: RouteDependen }, }, async (context, request, response) => { + const security = await getSecurity(); const result = await security.authc.apiKeys.create(request, request.body); if (result) { const apiKey = { ...result, beats_logstash_format: `${result.id}:${result.api_key}` }; diff --git a/x-pack/plugins/serverless_search/server/routes/indices_routes.ts b/x-pack/plugins/serverless_search/server/routes/indices_routes.ts index 1e54a64642115..0cf303b677454 100644 --- a/x-pack/plugins/serverless_search/server/routes/indices_routes.ts +++ b/x-pack/plugins/serverless_search/server/routes/indices_routes.ts @@ -14,7 +14,7 @@ import { fetchIndices } from '../lib/indices/fetch_indices'; import { fetchIndex } from '../lib/indices/fetch_index'; import { RouteDependencies } from '../plugin'; -export const registerIndicesRoutes = ({ router, security }: RouteDependencies) => { +export const registerIndicesRoutes = ({ router, getSecurity }: RouteDependencies) => { router.get( { path: '/internal/serverless_search/indices', @@ -28,6 +28,7 @@ export const registerIndicesRoutes = ({ router, security }: RouteDependencies) = }, async (context, request, response) => { const client = (await context.core).elasticsearch.client.asCurrentUser; + const security = await getSecurity(); const user = security.authc.getCurrentUser(request); if (!user) { diff --git a/x-pack/plugins/spaces/server/default_space/create_default_space.test.ts b/x-pack/plugins/spaces/server/default_space/create_default_space.test.ts index 25a98d09a2bb8..e7a7b51b278d1 100644 --- a/x-pack/plugins/spaces/server/default_space/create_default_space.test.ts +++ b/x-pack/plugins/spaces/server/default_space/create_default_space.test.ts @@ -106,7 +106,7 @@ test(`it throws all other errors from the saved objects client when checking for simulateGetErrorCondition: true, }); - expect(createDefaultSpace(deps)).rejects.toThrowErrorMatchingInlineSnapshot( + await expect(createDefaultSpace(deps)).rejects.toThrowErrorMatchingInlineSnapshot( `"unit test: unexpected exception condition"` ); }); @@ -131,7 +131,7 @@ test(`it throws other errors if there is an error creating the default space`, a simulateCreateErrorCondition: true, }); - expect(createDefaultSpace(deps)).rejects.toThrowErrorMatchingInlineSnapshot( + await expect(createDefaultSpace(deps)).rejects.toThrowErrorMatchingInlineSnapshot( `"unit test: some other unexpected error"` ); }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts index 0c866de5bde66..e772ad389e8f9 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts @@ -24,7 +24,7 @@ const areObjectsUnique = (objects: SavedObjectIdentifier[]) => _.uniqBy(objects, (o: SavedObjectIdentifier) => `${o.type}:${o.id}`).length === objects.length; export function initCopyToSpacesApi(deps: ExternalRouteDeps) { - const { router, getSpacesService, usageStatsServicePromise, getStartServices } = deps; + const { router, getSpacesService, usageStatsServicePromise, getStartServices, log } = deps; const usageStatsClientPromise = usageStatsServicePromise.then(({ getClient }) => getClient()); router.post( @@ -96,14 +96,20 @@ export function initCopyToSpacesApi(deps: ExternalRouteDeps) { } = request.body; const { headers } = request; - usageStatsClientPromise.then((usageStatsClient) => - usageStatsClient.incrementCopySavedObjects({ - headers, - createNewCopies, - overwrite, - compatibilityMode, - }) - ); + usageStatsClientPromise + .then((usageStatsClient) => + usageStatsClient.incrementCopySavedObjects({ + headers, + createNewCopies, + overwrite, + compatibilityMode, + }) + ) + .catch((err) => { + log.error( + `Failed to report usage statistics for the copy saved objects route: ${err.message}` + ); + }); try { const copySavedObjectsToSpaces = copySavedObjectsToSpacesFactory( @@ -198,13 +204,19 @@ export function initCopyToSpacesApi(deps: ExternalRouteDeps) { request.body; const { headers } = request; - usageStatsClientPromise.then((usageStatsClient) => - usageStatsClient.incrementResolveCopySavedObjectsErrors({ - headers, - createNewCopies, - compatibilityMode, - }) - ); + usageStatsClientPromise + .then((usageStatsClient) => + usageStatsClient.incrementResolveCopySavedObjectsErrors({ + headers, + createNewCopies, + compatibilityMode, + }) + ) + .catch((err) => { + log.error( + `Failed to report usage statistics for the resolve copy saved objects errors route: ${err.message}` + ); + }); const resolveCopySavedObjectsToSpacesConflicts = resolveCopySavedObjectsToSpacesConflictsFactory(startServices.savedObjects, request); diff --git a/x-pack/plugins/spaces/server/routes/api/external/disable_legacy_url_aliases.ts b/x-pack/plugins/spaces/server/routes/api/external/disable_legacy_url_aliases.ts index 725d0c87612fb..d708618f43870 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/disable_legacy_url_aliases.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/disable_legacy_url_aliases.ts @@ -12,7 +12,7 @@ import { wrapError } from '../../../lib/errors'; import { createLicensedRouteHandler } from '../../lib'; export function initDisableLegacyUrlAliasesApi(deps: ExternalRouteDeps) { - const { router, getSpacesService, usageStatsServicePromise } = deps; + const { router, getSpacesService, usageStatsServicePromise, log } = deps; const usageStatsClientPromise = usageStatsServicePromise.then(({ getClient }) => getClient()); router.post( @@ -35,9 +35,13 @@ export function initDisableLegacyUrlAliasesApi(deps: ExternalRouteDeps) { const { aliases } = request.body; - usageStatsClientPromise.then((usageStatsClient) => - usageStatsClient.incrementDisableLegacyUrlAliases() - ); + usageStatsClientPromise + .then((usageStatsClient) => usageStatsClient.incrementDisableLegacyUrlAliases()) + .catch((err) => { + log.error( + `Failed to report usage statistics for the disable legacy URL aliases route: ${err.message}` + ); + }); try { await spacesClient.disableLegacyUrlAliases(aliases); diff --git a/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts b/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts index 67c926229601b..0f689cd492e11 100644 --- a/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts +++ b/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts @@ -251,7 +251,7 @@ describe('#create', () => { const client = new SpacesClient(mockDebugLogger, mockConfig, mockCallWithRequestRepository, []); - expect(client.create(spaceToCreate)).rejects.toThrowErrorMatchingInlineSnapshot( + await expect(client.create(spaceToCreate)).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to create Space, this exceeds the maximum number of spaces set by the xpack.spaces.maxSpaces setting"` ); @@ -321,7 +321,7 @@ describe('#create', () => { [] ); - expect( + await expect( client.create({ ...spaceToCreate, disabledFeatures: ['some-feature'] }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to create Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled"` @@ -429,7 +429,7 @@ describe('#update', () => { ); const id = savedObject.id; - expect( + await expect( client.update(id, { ...spaceToUpdate, disabledFeatures: ['some-feature'] }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to update Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled"` @@ -475,7 +475,7 @@ describe('#delete', () => { const client = new SpacesClient(mockDebugLogger, mockConfig, mockCallWithRequestRepository, []); - expect(client.delete(id)).rejects.toThrowErrorMatchingInlineSnapshot( + await expect(client.delete(id)).rejects.toThrowErrorMatchingInlineSnapshot( `"The foo space cannot be deleted because it is reserved."` ); diff --git a/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_shape_filters.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_shape_filters.test.ts index a133d65d871aa..5b48bd6512e9d 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_shape_filters.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_shape_filters.test.ts @@ -129,7 +129,7 @@ describe('getShapeFilters', () => { throw new Error('Simulated elasticsearch search error'); }, } as unknown as ElasticsearchClient; - expect(async () => { + await expect(async () => { await getShapeFilters(boundariesRequestMeta, mockEsClient); }).rejects.toThrow(); }); @@ -144,7 +144,7 @@ describe('getShapeFilters', () => { }; }, } as unknown as ElasticsearchClient; - expect(async () => { + await expect(async () => { await getShapeFilters(boundariesRequestMeta, mockEsClient); }).rejects.toThrow(); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts index 1c3972dd680b2..69836a5b95e29 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_sir/service.ts @@ -38,7 +38,7 @@ export const createExternalService: ServiceFactory = ({ }); const _addObservable = async (data: Observable | Observable[], url: string) => { - snService.checkIfApplicationIsInstalled(); + await snService.checkIfApplicationIsInstalled(); const res = await request({ axios: axiosInstance, diff --git a/x-pack/plugins/task_manager/server/buffered_task_store.test.ts b/x-pack/plugins/task_manager/server/buffered_task_store.test.ts index 458b9d4c4bd2a..fa7a59478728d 100644 --- a/x-pack/plugins/task_manager/server/buffered_task_store.test.ts +++ b/x-pack/plugins/task_manager/server/buffered_task_store.test.ts @@ -135,7 +135,7 @@ describe('Buffered Task Store', () => { bufferedStore.update(tasks[2], { validate: true }), ]; expect(await results[0]).toMatchObject(tasks[0]); - expect(results[1]).rejects.toMatchInlineSnapshot(` + await expect(results[1]).rejects.toMatchInlineSnapshot(` Object { "error": Object { "error": "Oh no, something went terribly wrong", diff --git a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts index 99bb7c5b84274..00dd7e00d27e2 100644 --- a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts +++ b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts @@ -69,28 +69,21 @@ describe('Bulk Operation Buffer', () => { const task3 = createTask(); const task4 = createTask(); - return new Promise((resolve) => { - Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then((_) => { - expect(bulkUpdate).toHaveBeenCalledTimes(1); - expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - expect(bulkUpdate).not.toHaveBeenCalledWith([task3, task4]); - }); - - setTimeout(() => { - // on next tick - expect(bulkUpdate).toHaveBeenCalledTimes(1); - Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]).then((_) => { - expect(bulkUpdate).toHaveBeenCalledTimes(2); - expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); - }); - - setTimeout(() => { - // on next tick - expect(bulkUpdate).toHaveBeenCalledTimes(2); - resolve(); - }, bufferMaxDuration * 1.1); - }, bufferMaxDuration * 1.1); - }); + await Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]); + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).not.toHaveBeenCalledWith([task3, task4]); + + await new Promise((resolve) => setTimeout(resolve, bufferMaxDuration * 1.1)); + // on next tick + expect(bulkUpdate).toHaveBeenCalledTimes(1); + await Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]); + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + + await new Promise((resolve) => setTimeout(resolve, bufferMaxDuration * 1.1)); + // on next tick + expect(bulkUpdate).toHaveBeenCalledTimes(2); }); test('batch updates are executed once queue hits a certain bound', async () => { @@ -110,20 +103,19 @@ describe('Bulk Operation Buffer', () => { const task4 = createTask(); const task5 = createTask(); - return Promise.all([ + await Promise.all([ bufferedUpdate(task1), bufferedUpdate(task2), bufferedUpdate(task3), bufferedUpdate(task4), - ]).then(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(2); - expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); - return bufferedUpdate(task5).then((_) => { - expect(bulkUpdate).toHaveBeenCalledTimes(3); - expect(bulkUpdate).toHaveBeenCalledWith([task5]); - }); - }); + ]); + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + + await bufferedUpdate(task5); + expect(bulkUpdate).toHaveBeenCalledTimes(3); + expect(bulkUpdate).toHaveBeenCalledWith([task5]); }); test('queue upper bound is reset after each flush', async () => { @@ -142,24 +134,17 @@ describe('Bulk Operation Buffer', () => { const task3 = createTask(); const task4 = createTask(); - return Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(1); - expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - - return new Promise((resolve) => { - const futureUpdates = Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]); + await Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]); + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - setTimeout(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(1); + const futureUpdates = Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]); + await new Promise((resolve) => setTimeout(resolve, bufferMaxDuration / 2)); + expect(bulkUpdate).toHaveBeenCalledTimes(1); - futureUpdates.then(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(2); - expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); - resolve(); - }); - }, bufferMaxDuration / 2); - }); - }); + await futureUpdates; + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); }); test('handles both resolutions and rejections at individual task level', async () => { diff --git a/x-pack/plugins/task_manager/server/lib/remove_if_exists.test.ts b/x-pack/plugins/task_manager/server/lib/remove_if_exists.test.ts index 748e529ef1446..1270f1aedae6f 100644 --- a/x-pack/plugins/task_manager/server/lib/remove_if_exists.test.ts +++ b/x-pack/plugins/task_manager/server/lib/remove_if_exists.test.ts @@ -38,7 +38,7 @@ describe('removeIfExists', () => { const error = SavedObjectsErrorHelpers.createInvalidVersionError(uuidv4()); ts.remove.mockRejectedValue(error); - expect(removeIfExists(ts, id)).rejects.toBe(error); + await expect(removeIfExists(ts, id)).rejects.toBe(error); expect(ts.remove).toHaveBeenCalledWith(id); }); diff --git a/x-pack/plugins/task_manager/server/lib/result_type.test.ts b/x-pack/plugins/task_manager/server/lib/result_type.test.ts index d35f00d30920c..4dc2f5f071278 100644 --- a/x-pack/plugins/task_manager/server/lib/result_type.test.ts +++ b/x-pack/plugins/task_manager/server/lib/result_type.test.ts @@ -17,12 +17,12 @@ describe(`Result`, () => { test(`unwraps Errs from the result`, async () => { const uniqueId = uuidv4(); - expect(unwrapPromise(Promise.resolve(asErr(uniqueId)))).rejects.toEqual(uniqueId); + await expect(unwrapPromise(Promise.resolve(asErr(uniqueId)))).rejects.toEqual(uniqueId); }); test(`unwraps Errs from the result when promise rejects`, async () => { const uniqueId = uuidv4(); - expect(unwrapPromise(Promise.reject(asErr(uniqueId)))).rejects.toEqual(uniqueId); + await expect(unwrapPromise(Promise.reject(asErr(uniqueId)))).rejects.toEqual(uniqueId); }); }); }); diff --git a/x-pack/plugins/task_manager/server/metrics/task_metrics_collector.ts b/x-pack/plugins/task_manager/server/metrics/task_metrics_collector.ts index d588a001693b9..2d87f789128cd 100644 --- a/x-pack/plugins/task_manager/server/metrics/task_metrics_collector.ts +++ b/x-pack/plugins/task_manager/server/metrics/task_metrics_collector.ts @@ -64,7 +64,7 @@ export class TaskManagerMetricsCollector implements ITaskEventEmitter {}); } } diff --git a/x-pack/plugins/task_manager/server/mocks.ts b/x-pack/plugins/task_manager/server/mocks.ts index 45a2f117167ca..71638bc883681 100644 --- a/x-pack/plugins/task_manager/server/mocks.ts +++ b/x-pack/plugins/task_manager/server/mocks.ts @@ -29,7 +29,7 @@ const createStartMock = () => { runSoon: jest.fn(), ephemeralRunNow: jest.fn(), ensureScheduled: jest.fn(), - removeIfExists: jest.fn(), + removeIfExists: jest.fn().mockResolvedValue(Promise.resolve()), // it's a promise and there are some places where it's followed by `.catch()` supportsEphemeralTasks: jest.fn(), bulkUpdateSchedules: jest.fn(), bulkSchedule: jest.fn(), diff --git a/x-pack/plugins/task_manager/server/polling/task_poller.ts b/x-pack/plugins/task_manager/server/polling/task_poller.ts index ff984a44f1aa0..570ecc8686693 100644 --- a/x-pack/plugins/task_manager/server/polling/task_poller.ts +++ b/x-pack/plugins/task_manager/server/polling/task_poller.ts @@ -72,7 +72,7 @@ export function createTaskPoller({ if (running) { // Set the next runCycle call timeoutId = setTimeout( - runCycle, + () => runCycle().catch(() => {}), Math.max(pollInterval - (Date.now() - start) + (pollIntervalDelay % pollInterval), 0) ); // Reset delay, it's designed to shuffle only once @@ -111,7 +111,7 @@ export function createTaskPoller({ start: () => { if (!running) { running = true; - runCycle(); + runCycle().catch(() => {}); // We need to subscribe shortly after start. Otherwise, the observables start emiting events // too soon for the task run statistics module to capture. setTimeout(() => subscribe(), 0); diff --git a/x-pack/plugins/task_manager/server/task_pool.ts b/x-pack/plugins/task_manager/server/task_pool.ts index a3a047cd735c9..c0784f0458f72 100644 --- a/x-pack/plugins/task_manager/server/task_pool.ts +++ b/x-pack/plugins/task_manager/server/task_pool.ts @@ -198,7 +198,8 @@ export class TaskPool { }) .then(() => { this.tasksInPool.delete(taskRunner.taskExecutionId); - }); + }) + .catch(() => {}); } private handleFailureOfMarkAsRunning(task: TaskRunner, err: Error) { @@ -227,14 +228,17 @@ export class TaskPool { } } - private async cancelTask(task: TaskRunner) { - try { - this.logger.debug(`Cancelling task ${task.toString()}.`); - this.tasksInPool.delete(task.taskExecutionId); - await task.cancel(); - } catch (err) { - this.logger.error(`Failed to cancel task ${task.toString()}: ${err}`); - } + private cancelTask(task: TaskRunner) { + // internally async (without rejections), but public-facing is synchronous + (async () => { + try { + this.logger.debug(`Cancelling task ${task.toString()}.`); + this.tasksInPool.delete(task.taskExecutionId); + await task.cancel(); + } catch (err) { + this.logger.error(`Failed to cancel task ${task.toString()}: ${err}`); + } + })().catch(() => {}); } } diff --git a/x-pack/plugins/task_manager/server/task_scheduling.test.ts b/x-pack/plugins/task_manager/server/task_scheduling.test.ts index f4c8c0d6b0880..36de95416e1ca 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.test.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.test.ts @@ -836,7 +836,8 @@ describe('TaskScheduling', () => { }); describe('ephemeralRunNow', () => { - test('runs a task ephemerally', async () => { + // https://github.com/elastic/kibana/issues/181847 + test.skip('runs a task ephemerally', async () => { const ephemeralEvents$ = new Subject(); const ephemeralTask = taskManagerMock.createTask({ state: { @@ -880,7 +881,7 @@ describe('TaskScheduling', () => { ) ); - expect(result).resolves.toEqual({ id: 'v4uuid', state: { foo: 'bar' } }); + await expect(result).resolves.toEqual({ id: 'v4uuid', state: { foo: 'bar' } }); }); test('rejects ephemeral task if lifecycle returns an error', async () => { @@ -924,7 +925,7 @@ describe('TaskScheduling', () => { ) ); - expect(result).rejects.toMatchInlineSnapshot( + await expect(result).rejects.toMatchInlineSnapshot( `[Error: Ephemeral Task of type foo was rejected]` ); }); @@ -946,7 +947,7 @@ describe('TaskScheduling', () => { }); const result = taskScheduling.ephemeralRunNow(ephemeralTask); - expect(result).rejects.toMatchInlineSnapshot( + await expect(result).rejects.toMatchInlineSnapshot( `[Error: Ephemeral Task of type foo was rejected because ephemeral tasks are not supported]` ); }); diff --git a/x-pack/plugins/task_manager/server/task_scheduling.ts b/x-pack/plugins/task_manager/server/task_scheduling.ts index 7cb13182820b7..c57e54c76a98d 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.ts @@ -414,9 +414,11 @@ export class TaskScheduling { }); if (cancel) { - cancel.then(() => { - subscription.unsubscribe(); - }); + cancel + .then(() => { + subscription.unsubscribe(); + }) + .catch(() => {}); } }); } diff --git a/x-pack/plugins/threat_intelligence/server/plugin.ts b/x-pack/plugins/threat_intelligence/server/plugin.ts index d6fb0cb20aeee..91690b266d564 100644 --- a/x-pack/plugins/threat_intelligence/server/plugin.ts +++ b/x-pack/plugins/threat_intelligence/server/plugin.ts @@ -30,7 +30,7 @@ export class ThreatIntelligencePlugin implements IThreatIntelligencePlugin { ) { this.logger.debug('setup'); - core.getStartServices().then(([_, { data: dataStartService }]) => { + void core.getStartServices().then(([_, { data: dataStartService }]) => { const threatIntelligenceSearchStrategy = threatIntelligenceSearchStrategyProvider(dataStartService); diff --git a/x-pack/plugins/timelines/server/plugin.ts b/x-pack/plugins/timelines/server/plugin.ts index 2f8406b2b5646..619c66a05ee30 100644 --- a/x-pack/plugins/timelines/server/plugin.ts +++ b/x-pack/plugins/timelines/server/plugin.ts @@ -29,7 +29,7 @@ export class TimelinesPlugin const IndexFields = indexFieldsProvider(core.getStartServices); // Register search strategy - core.getStartServices().then(([_, depsStart]) => { + void core.getStartServices().then(([_, depsStart]) => { const TimelineSearchStrategy = timelineSearchStrategyProvider( depsStart.data, this.logger, diff --git a/x-pack/plugins/transform/server/plugin.ts b/x-pack/plugins/transform/server/plugin.ts index 6188a809c910c..6ca3eb92388f3 100644 --- a/x-pack/plugins/transform/server/plugin.ts +++ b/x-pack/plugins/transform/server/plugin.ts @@ -71,32 +71,41 @@ export class TransformServerPlugin implements Plugin<{}, void, any, any> { ], }); - getStartServices().then(([coreStart, { dataViews, security: securityStart }]) => { - const license = new License({ - pluginId: PLUGIN.id, - minimumLicenseType: PLUGIN.minimumLicenseType, - defaultErrorMessage: i18n.translate('xpack.transform.licenseCheckErrorMessage', { - defaultMessage: 'License check failed', - }), - licensing, - logger: this.logger, - coreStart, - }); + registerRoutes({ + router: http.createRouter(), + getLicense: async () => { + const [coreStart] = await getStartServices(); + return new License({ + pluginId: PLUGIN.id, + minimumLicenseType: PLUGIN.minimumLicenseType, + defaultErrorMessage: i18n.translate('xpack.transform.licenseCheckErrorMessage', { + defaultMessage: 'License check failed', + }), + licensing, + logger: this.logger, + coreStart, + }); + }, + getDataViewsStart: async () => { + const [, { dataViews }] = await getStartServices(); + return dataViews; + }, + getCoreStart: async () => { + const [coreStart] = await getStartServices(); + return coreStart; + }, + getSecurity: async () => { + const [, { security }] = await getStartServices(); + return security; + }, + }); - registerRoutes({ - router: http.createRouter(), - license, - dataViews, - coreStart, - security: securityStart, + if (usageCollection) { + registerCollector(usageCollection, async () => { + const [coreStart] = await getStartServices(); + return coreStart.savedObjects.getIndexForType('alert'); }); - - const alertIndex = coreStart.savedObjects.getIndexForType('alert'); - - if (usageCollection) { - registerCollector(usageCollection, alertIndex); - } - }); + } if (alerting) { registerTransformHealthRuleType({ diff --git a/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts b/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts index e5357034a1cbd..be1c0ef34ccae 100644 --- a/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts @@ -17,7 +17,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms Audit Messages * @@ -42,10 +42,13 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute< - TransformIdParamSchema, - GetTransformAuditMessagesQuerySchema, - undefined - >(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute< + TransformIdParamSchema, + GetTransformAuditMessagesQuerySchema, + undefined + >(routeHandler)(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts index cdb58c02d9664..3646889f2c005 100644 --- a/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts @@ -16,7 +16,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandlerFactory } from './route_handler_factory'; export function registerRoute(routeDependencies: RouteDependencies) { - const { router, license } = routeDependencies; + const { router, getLicense } = routeDependencies; /** * @apiGroup Transforms * @@ -40,8 +40,11 @@ export function registerRoute(routeDependencies: RouteDependencies) { }, }, }, - license.guardApiRoute( - routeHandlerFactory(routeDependencies) - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandlerFactory(routeDependencies) + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/delete_transforms/route_handler_factory.ts b/x-pack/plugins/transform/server/routes/api/delete_transforms/route_handler_factory.ts index c20dee6c68b98..c55fa798d24eb 100644 --- a/x-pack/plugins/transform/server/routes/api/delete_transforms/route_handler_factory.ts +++ b/x-pack/plugins/transform/server/routes/api/delete_transforms/route_handler_factory.ts @@ -24,13 +24,14 @@ export const routeHandlerFactory: ( DeleteTransformsRequestSchema, TransformRequestHandlerContext > = - ({ coreStart, dataViews }) => + ({ getCoreStart, getDataViewsStart }) => async (ctx, req, res) => { try { - const { savedObjects, elasticsearch } = coreStart; + const { savedObjects, elasticsearch } = await getCoreStart(); const savedObjectsClient = savedObjects.getScopedClient(req); const esClient = elasticsearch.client.asScoped(req).asCurrentUser; + const dataViews = await getDataViewsStart(); const dataViewsService = await dataViews.dataViewsServiceFactory( savedObjectsClient, esClient, diff --git a/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts b/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts index 4f8819b865f86..d1949f06e1ca5 100644 --- a/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { router.versioned .post({ path: addInternalBasePath('field_histograms/{dataViewTitle}'), @@ -31,8 +31,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute( - routeHandler - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts index 017aa98e76304..fc5128e0971b6 100644 --- a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts @@ -14,7 +14,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandlerFactory } from './route_handler_factory'; export function registerRoute(routeDependencies: RouteDependencies) { - const { router, license } = routeDependencies; + const { router, getLicense } = routeDependencies; /** * @apiGroup Reauthorize transforms with API key generated from currently logged in user * @api {post} /internal/transform/reauthorize_transforms Post reauthorize transforms @@ -38,8 +38,11 @@ export function registerRoute(routeDependencies: RouteDependencies) { }, }, }, - license.guardApiRoute( - routeHandlerFactory(routeDependencies) - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandlerFactory(routeDependencies) + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/route_handler_factory.ts b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/route_handler_factory.ts index acefdec0257a9..aa63936a3f6e7 100644 --- a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/route_handler_factory.ts +++ b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/route_handler_factory.ts @@ -26,7 +26,9 @@ export const routeHandlerFactory: ( StartTransformsRequestSchema, TransformRequestHandlerContext > = (routeDependencies) => async (ctx, req, res) => { - const { coreStart, security: securityStart } = routeDependencies; + const { getCoreStart, getSecurity } = routeDependencies; + const coreStart = await getCoreStart(); + const securityStart = await getSecurity(); try { const transformsInfo = req.body; diff --git a/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts index cae6245455810..adbe55b8e828d 100644 --- a/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -39,6 +39,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts index cf19b56c316f1..0ec8808ae2ecf 100644 --- a/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -39,6 +39,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts index 5cba3a5a01d70..5ce3de48e63a3 100644 --- a/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -39,6 +39,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts index df9498f9ae033..b859ee4743c40 100644 --- a/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -39,6 +39,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts index e808e0e8fafc2..29cbd34bffd68 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts @@ -13,7 +13,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -29,13 +29,16 @@ export function registerRoute({ router, license }: RouteDependencies) { path: addInternalBasePath('transforms'), access: 'internal', }) - .addVersion( + .addVersion( { version: '1', validate: false, }, - license.guardApiRoute( - routeHandler - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts index f6be9e18893f2..9237977118d05 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts @@ -25,7 +25,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandlerFactory } from './route_handler_factory'; export function registerRoute(routeDependencies: RouteDependencies) { - const { router, license } = routeDependencies; + const { router, getLicense } = routeDependencies; /** * @apiGroup Transforms @@ -54,10 +54,13 @@ export function registerRoute(routeDependencies: RouteDependencies) { }, }, }, - license.guardApiRoute< - TransformIdParamSchema, - DataViewCreateQuerySchema, - PutTransformsRequestSchema - >(routeHandlerFactory(routeDependencies)) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute< + TransformIdParamSchema, + DataViewCreateQuerySchema, + PutTransformsRequestSchema + >(routeHandlerFactory(routeDependencies))(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_create/route_handler_factory.ts b/x-pack/plugins/transform/server/routes/api/transforms_create/route_handler_factory.ts index 8ca98efe3cb54..0baa019808e8b 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_create/route_handler_factory.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_create/route_handler_factory.ts @@ -31,7 +31,9 @@ export const routeHandlerFactory: ( PutTransformsRequestSchema, TransformRequestHandlerContext > = (routeDependencies) => async (ctx, req, res) => { - const { coreStart, dataViews } = routeDependencies; + const { getCoreStart, getDataViewsStart } = routeDependencies; + const coreStart = await getCoreStart(); + const dataViews = await getDataViewsStart(); const { transformId } = req.params; const { createDataView, timeFieldName } = req.query; diff --git a/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts index f1a75d9f9ef28..701306ff6481c 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts @@ -11,7 +11,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandlerFactory } from './route_handler_factory'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transform Nodes * @@ -29,6 +29,13 @@ export function registerRoute({ router, license }: RouteDependencies) { version: '1', validate: false, }, - license.guardApiRoute(routeHandlerFactory(license)) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute(routeHandlerFactory(license))( + ctx, + request, + response + ); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_nodes/route_handler_factory.ts b/x-pack/plugins/transform/server/routes/api/transforms_nodes/route_handler_factory.ts index c512bfd58594a..10171f948c2ad 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes/route_handler_factory.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes/route_handler_factory.ts @@ -9,10 +9,9 @@ import Boom from '@hapi/boom'; import type { RequestHandler } from '@kbn/core/server'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import type { License } from '../../../services'; import { NODES_INFO_PRIVILEGES } from '../../../../common/constants'; -import type { RouteDependencies } from '../../../types'; - import { wrapError, wrapEsError } from '../../utils/error_utils'; const NODE_ROLES = 'roles'; @@ -33,7 +32,7 @@ export const isNodes = (arg: unknown): arg is Nodes => { }; export const routeHandlerFactory: ( - license: RouteDependencies['license'] + license: License ) => RequestHandler = (license) => async (ctx, req, res) => { try { const esClient = (await ctx.core).elasticsearch.client; diff --git a/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts index 646f92271243b..55e1446dfe5aa 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts @@ -13,7 +13,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -37,6 +37,11 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute( + routeHandler + )(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts index e79446d3962c0..c13c2b996dc7f 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts @@ -15,7 +15,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -39,6 +39,13 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute(routeHandler)( + ctx, + request, + response + ); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts index ef0bf70ec96d1..8aa59649af1d4 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts @@ -17,7 +17,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -43,10 +43,13 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute< - estypes.TransformGetTransformStatsResponse, - GetTransformStatsQuerySchema, - undefined - >(routeHandler) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute< + estypes.TransformGetTransformStatsResponse, + GetTransformStatsQuerySchema, + undefined + >(routeHandler)(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts index a0e86fe7bf01c..9f7424cd62acf 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts @@ -19,7 +19,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -44,8 +44,13 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute( - routeHandler - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute< + TransformIdParamSchema, + GetTransformStatsQuerySchema, + undefined + >(routeHandler)(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts index 366b4ea32fc92..a90ce9395bfce 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts @@ -19,7 +19,7 @@ import type { RouteDependencies } from '../../../types'; import { routeHandler } from './route_handler'; -export function registerRoute({ router, license }: RouteDependencies) { +export function registerRoute({ router, getLicense }: RouteDependencies) { /** * @apiGroup Transforms * @@ -45,8 +45,13 @@ export function registerRoute({ router, license }: RouteDependencies) { }, }, }, - license.guardApiRoute( - routeHandler - ) + async (ctx, request, response) => { + const license = await getLicense(); + return license.guardApiRoute< + TransformIdParamSchema, + undefined, + PostTransformsUpdateRequestSchema + >(routeHandler)(ctx, request, response); + } ); } diff --git a/x-pack/plugins/transform/server/types.ts b/x-pack/plugins/transform/server/types.ts index d32f295fdf679..e5c44aafe163a 100644 --- a/x-pack/plugins/transform/server/types.ts +++ b/x-pack/plugins/transform/server/types.ts @@ -32,8 +32,8 @@ export interface PluginStartDependencies { export interface RouteDependencies { router: IRouter; - license: License; - coreStart: CoreStart; - dataViews: DataViewsServerPluginStart; - security?: SecurityPluginStart; + getLicense: () => Promise; + getCoreStart: () => Promise; + getDataViewsStart: () => Promise; + getSecurity: () => Promise; } diff --git a/x-pack/plugins/transform/server/usage/collector.ts b/x-pack/plugins/transform/server/usage/collector.ts index c2ee09ad983c1..98979375d4d49 100644 --- a/x-pack/plugins/transform/server/usage/collector.ts +++ b/x-pack/plugins/transform/server/usage/collector.ts @@ -22,7 +22,10 @@ export interface TransformAlertsUsageData { }; } -export function registerCollector(usageCollection: UsageCollectionSetup, alertIndex: string) { +export function registerCollector( + usageCollection: UsageCollectionSetup, + getAlertIndex: () => Promise +) { const collector = usageCollection.makeUsageCollector({ type: 'transform', schema: { @@ -62,7 +65,7 @@ export function registerCollector(usageCollection: UsageCollectionSetup, alertIn }; }>( { - index: alertIndex, + index: await getAlertIndex(), size: 10000, query: { bool: { diff --git a/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts index 9dfc32b6ee930..efc802dc73d3c 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts @@ -50,7 +50,7 @@ describe('timeSeriesQuery', () => { }); it('fails as expected when the query params are invalid', async () => { - expect( + await expect( timeSeriesQuery({ ...params, query: { ...params.query, dateStart: 'x' } }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"invalid date format for dateStart: \\"x\\""`); }); diff --git a/x-pack/plugins/triggers_actions_ui/server/plugin.ts b/x-pack/plugins/triggers_actions_ui/server/plugin.ts index 04de44a088ed5..b5cafb0571482 100644 --- a/x-pack/plugins/triggers_actions_ui/server/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/server/plugin.ts @@ -53,14 +53,15 @@ export class TriggersActionsPlugin implements Plugin plugins.alerting !== undefined ); - core.getStartServices().then(([_, pluginStart]) => { - createConfigRoute({ - logger: this.logger, - router, - baseRoute: BASE_TRIGGERS_ACTIONS_UI_API_PATH, - alertingConfig: plugins.alerting.getConfig, - getRulesClientWithRequest: pluginStart.alerting.getRulesClientWithRequest, - }); + createConfigRoute({ + logger: this.logger, + router, + baseRoute: BASE_TRIGGERS_ACTIONS_UI_API_PATH, + alertingConfig: plugins.alerting.getConfig, + getRulesClientWithRequest: async (request) => { + const [, pluginStart] = await core.getStartServices(); + return pluginStart.alerting.getRulesClientWithRequest(request); + }, }); } diff --git a/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts b/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts index 8918e77795520..c951a5f9d34d2 100644 --- a/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts +++ b/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts @@ -55,7 +55,7 @@ describe('createConfigRoute', () => { maxScheduledPerMinute: 10000, minimumScheduleInterval: { value: '1m', enforce: false }, }), - getRulesClientWithRequest: () => mockRulesClient, + getRulesClientWithRequest: async () => mockRulesClient, }); const [config, handler] = router.get.mock.calls[0]; @@ -89,7 +89,7 @@ describe('createConfigRoute', () => { maxScheduledPerMinute: 10000, minimumScheduleInterval: { value: '1m', enforce: false }, }), - getRulesClientWithRequest: () => mockRulesClient, + getRulesClientWithRequest: async () => mockRulesClient, }); const [config, handler] = router.get.mock.calls[0]; diff --git a/x-pack/plugins/triggers_actions_ui/server/routes/config.ts b/x-pack/plugins/triggers_actions_ui/server/routes/config.ts index 1cc328c0ae5ad..c0212d7dc824f 100644 --- a/x-pack/plugins/triggers_actions_ui/server/routes/config.ts +++ b/x-pack/plugins/triggers_actions_ui/server/routes/config.ts @@ -23,7 +23,7 @@ export interface ConfigRouteOpts { // alertingConfig is a function because "isUsingSecurity" is pulled from the license // state which gets populated after plugin setup(). alertingConfig: () => AlertingRulesConfig; - getRulesClientWithRequest: (request: KibanaRequest) => RulesClientApi; + getRulesClientWithRequest: (request: KibanaRequest) => Promise; } export function createConfigRoute({ @@ -48,7 +48,7 @@ export function createConfigRoute({ res: KibanaResponseFactory ): Promise { // Check that user has access to at least one rule type - const rulesClient = getRulesClientWithRequest(req); + const rulesClient = await getRulesClientWithRequest(req); const ruleTypes = Array.from(await rulesClient.listRuleTypes()); if (ruleTypes.length > 0) { return res.ok({ body: alertingConfig() }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts index 46fcf6a4cec5b..902c7e83c59b4 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts @@ -6,6 +6,7 @@ */ import { IClusterClient, Logger, SavedObjectsClientContract, FakeRequest } from '@kbn/core/server'; +import { exhaustMap, Subject, takeUntil, timer } from 'rxjs'; import moment from 'moment'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; @@ -41,9 +42,8 @@ const WORKER_PADDING_MS = 1000; */ export class ReindexWorker { private static workerSingleton?: ReindexWorker; - private continuePolling: boolean = false; + private readonly stop$ = new Subject(); private updateOperationLoopRunning: boolean = false; - private timeout?: NodeJS.Timeout; private inProgressOps: ReindexSavedObject[] = []; private readonly reindexService: ReindexService; private readonly log: Logger; @@ -95,12 +95,16 @@ export class ReindexWorker { } /** - * Begins loop (1) to begin checking for in progress reindex operations. + * Begins loop checking for in progress reindex operations. */ public start = () => { this.log.debug('Starting worker...'); - this.continuePolling = true; - this.pollForOperations(); + timer(0, POLL_INTERVAL) + .pipe( + takeUntil(this.stop$), + exhaustMap(() => this.pollForOperations()) + ) + .subscribe(); }; /** @@ -108,19 +112,18 @@ export class ReindexWorker { */ public stop = () => { this.log.debug('Stopping worker...'); - if (this.timeout) { - clearTimeout(this.timeout); - } - + this.stop$.next(); this.updateOperationLoopRunning = false; - this.continuePolling = false; }; /** * Should be called immediately after this server has started a new reindex operation. */ public forceRefresh = () => { - this.refresh(); + // We know refresh won't throw, but just in case it does in the future + this.refresh().catch((error) => { + this.log.warn(`Failed to force refresh the reindex operations: ${error}`); + }); }; /** @@ -153,6 +156,8 @@ export class ReindexWorker { await new Promise((resolve) => setTimeout(resolve, WORKER_PADDING_MS)); } } + } catch (error) { + this.log.warn(`Failed to update reindex operations: ${error}`); } finally { this.updateOperationLoopRunning = false; } @@ -162,10 +167,6 @@ export class ReindexWorker { this.log.debug(`Polling for reindex operations`); await this.refresh(); - - if (this.continuePolling) { - this.timeout = setTimeout(this.pollForOperations, POLL_INTERVAL); - } }; private getCredentialScopedReindexService = (credential: Credential) => { @@ -194,7 +195,7 @@ export class ReindexWorker { firstOpInQueue.attributes.indexName ); // Re-associate the credentials - this.credentialStore.update({ + await this.credentialStore.update({ reindexOp: firstOpInQueue, security: this.security, credential, @@ -213,7 +214,7 @@ export class ReindexWorker { await this.updateInProgressOps(); // If there are operations in progress and we're not already updating operations, kick off the update loop if (!this.updateOperationLoopRunning) { - this.startUpdateOperationLoop(); + await this.startUpdateOperationLoop(); } }; @@ -250,7 +251,7 @@ export class ReindexWorker { reindexOp = await swallowExceptions(service.processNextStep, this.log)(reindexOp); // Update credential store with most recent state. - this.credentialStore.update({ reindexOp, security: this.security, credential }); + await this.credentialStore.update({ reindexOp, security: this.security, credential }); }; } diff --git a/x-pack/plugins/upgrade_assistant/server/plugin.ts b/x-pack/plugins/upgrade_assistant/server/plugin.ts index 6dfb65be85d7b..a2753279e8f69 100644 --- a/x-pack/plugins/upgrade_assistant/server/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/server/plugin.ts @@ -147,7 +147,7 @@ export class UpgradeAssistantServerPlugin implements Plugin { registerRoutes(dependencies, this.getWorker.bind(this)); if (usageCollection) { - getStartServices().then(([{ elasticsearch }]) => { + void getStartServices().then(([{ elasticsearch }]) => { registerUpgradeAssistantUsageCollector({ elasticsearch, usageCollection, diff --git a/x-pack/test/functional_cors/plugins/kibana_cors_test/server/plugin.ts b/x-pack/test/functional_cors/plugins/kibana_cors_test/server/plugin.ts index 13fd8307a24a3..b13505a081ae9 100644 --- a/x-pack/test/functional_cors/plugins/kibana_cors_test/server/plugin.ts +++ b/x-pack/test/functional_cors/plugins/kibana_cors_test/server/plugin.ts @@ -75,12 +75,12 @@ export class CorsTestPlugin implements Plugin { return h.response(renderBody(kibanaUrl)); }, }); - server.start(); + void server.start(); } public stop() { if (this.server) { - this.server.stop(); + void this.server.stop(); } } } diff --git a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/init_routes.ts b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/init_routes.ts index 7d5118c5d93d3..e4a8bc76a8908 100644 --- a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/init_routes.ts +++ b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/init_routes.ts @@ -75,9 +75,9 @@ export function initRoutes( }, Promise.resolve(undefined)); return res.ok({ - body: await new Promise((resolve) => { + body: await new Promise((resolve, reject) => { setTimeout(() => { - performanceApi.endCapture().then((perf) => resolve(perf)); + performanceApi.endCapture().then((perf) => resolve(perf), reject); }, durationInSeconds * 1000 + 10000 /* wait extra 10s to drain queue */); }), }); From d8831961e868587deb9e72b0c135837977ad6199 Mon Sep 17 00:00:00 2001 From: Kevin Lacabane Date: Wed, 1 May 2024 17:50:55 +0200 Subject: [PATCH 103/104] [Obs AI Assistant] register alert details context in observability plugin (#181501) ## Summary Closes https://github.com/elastic/kibana/issues/181286 Create a AlertDetailsContextService in `observability` plugin. The service can be used by solutions to register data handler fetching information relevant to an alert context which is then used as an input to the ai assistant when asked to investigate an alert. While only one handler is currently registered from apm plugin, the benefits are 1. making this information available to the ai assistant connector since it can't directly call apm api and 2. extending the context with additional data in the future, for example logs. #### Follow up - Move apm route and associated tests to observability plugin --- .../lib/helpers/get_apm_alerts_client.ts | 5 +- .../lib/helpers/get_apm_event_client.ts | 3 +- .../apm/server/lib/helpers/get_ml_client.ts | 6 +- .../apm/server/plugin.ts | 7 +- .../get_changepoints/index.ts | 146 +++++++++++++++ .../get_log_categories/index.ts | 2 +- .../get_alert_details_context_handler.ts | 85 +++++++++ .../get_apm_alert_details_context_prompt.ts | 85 +++++++++ .../get_container_id_from_signals.ts | 6 +- .../get_service_name_from_signals.ts | 6 +- .../index.ts | 166 ++---------------- .../routes/assistant_functions/route.ts | 42 ++--- .../alert_details_contextual_insights.tsx | 62 +------ .../observability/server/plugin.ts | 7 + .../server/routes/register_routes.ts | 4 + .../server/services/index.test.ts | 29 +++ .../observability/server/services/index.ts | 87 +++++++++ .../server/routes/types.ts | 1 + .../kibana.jsonc | 1 + .../server/plugin.ts | 8 +- .../server/rule_connector/index.test.ts | 36 +++- .../server/rule_connector/index.ts | 97 ++++++++-- .../server/types.ts | 2 + .../tsconfig.json | 1 + .../obs_alert_details_context.spec.ts | 157 ++++++++++------- 25 files changed, 711 insertions(+), 340 deletions(-) create mode 100644 x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_changepoints/index.ts create mode 100644 x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_alert_details_context_handler.ts create mode 100644 x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_apm_alert_details_context_prompt.ts create mode 100644 x-pack/plugins/observability_solution/observability/server/services/index.test.ts create mode 100644 x-pack/plugins/observability_solution/observability/server/services/index.ts diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts index 63b62d183da4c..3c885eef658d5 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts @@ -12,7 +12,10 @@ import type { MinimalAPMRouteHandlerResources } from '../../routes/apm_routes/re export type ApmAlertsClient = Awaited>; -export async function getApmAlertsClient({ plugins, request }: MinimalAPMRouteHandlerResources) { +export async function getApmAlertsClient({ + plugins, + request, +}: Pick) { const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest(request); const apmAlertsIndices = await alertsClient.getAuthorizedAlertsIndices(['apm']); diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_event_client.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_event_client.ts index 3b80c5ede61d3..b756876eb3212 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_event_client.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_event_client.ts @@ -13,12 +13,11 @@ import { MinimalAPMRouteHandlerResources } from '../../routes/apm_routes/registe export async function getApmEventClient({ context, params, - config, getApmIndices, request, }: Pick< MinimalAPMRouteHandlerResources, - 'context' | 'params' | 'config' | 'getApmIndices' | 'request' + 'context' | 'params' | 'getApmIndices' | 'request' >): Promise { return withApmSpan('get_apm_event_client', async () => { const coreContext = await context.core; diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_ml_client.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_ml_client.ts index 16b19b7ebed4f..b94a1abd67e2a 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_ml_client.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_ml_client.ts @@ -15,7 +15,11 @@ export interface MlClient { modules: MlModules; } -export async function getMlClient({ plugins, context, request }: MinimalAPMRouteHandlerResources) { +export async function getMlClient({ + plugins, + context, + request, +}: Pick) { const [coreContext, licensingContext] = await Promise.all([context.core, context.licensing]); const mlplugin = plugins.ml; diff --git a/x-pack/plugins/observability_solution/apm/server/plugin.ts b/x-pack/plugins/observability_solution/apm/server/plugin.ts index 415fd90af7daa..2c2392b845415 100644 --- a/x-pack/plugins/observability_solution/apm/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm/server/plugin.ts @@ -40,6 +40,7 @@ import { createApmSourceMapIndexTemplate } from './routes/source_maps/create_apm import { addApiKeysToEveryPackagePolicyIfMissing } from './routes/fleet/api_keys/add_api_keys_to_policies_if_missing'; import { apmTutorialCustomIntegration } from '../common/tutorial/tutorials'; import { registerAssistantFunctions } from './assistant_functions'; +import { getAlertDetailsContextHandler } from './routes/assistant_functions/get_observability_alert_details_context/get_alert_details_context_handler'; export class APMPlugin implements Plugin @@ -52,7 +53,7 @@ export class APMPlugin } public setup(core: CoreSetup, plugins: APMPluginSetupDependencies) { - this.logger = this.initContext.logger.get(); + const logger = (this.logger = this.initContext.logger.get()); const config$ = this.initContext.config.create(); core.savedObjects.registerType(apmTelemetry); @@ -221,6 +222,10 @@ export class APMPlugin }) ); + plugins.observability.alertDetailsContextualInsightsService.registerHandler( + getAlertDetailsContextHandler(resourcePlugins, logger) + ); + return { config$ }; } diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_changepoints/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_changepoints/index.ts new file mode 100644 index 0000000000000..2ffbdc30a1c52 --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_changepoints/index.ts @@ -0,0 +1,146 @@ +/* + * 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 { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmTimeseriesType, getApmTimeseries, TimeseriesChangePoint } from '../get_apm_timeseries'; + +export interface ChangePointGrouping { + title: string; + grouping: string; + changes: TimeseriesChangePoint[]; +} + +export async function getServiceChangePoints({ + apmEventClient, + alertStartedAt, + serviceName, + serviceEnvironment, + transactionType, + transactionName, +}: { + apmEventClient: APMEventClient; + alertStartedAt: string; + serviceName: string | undefined; + serviceEnvironment: string | undefined; + transactionType: string | undefined; + transactionName: string | undefined; +}): Promise { + if (!serviceName) { + return []; + } + + const res = await getApmTimeseries({ + apmEventClient, + arguments: { + start: moment(alertStartedAt).subtract(12, 'hours').toISOString(), + end: alertStartedAt, + stats: [ + { + title: 'Latency', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.transactionLatency, + function: LatencyAggregationType.p95, + 'transaction.type': transactionType, + 'transaction.name': transactionName, + }, + }, + { + title: 'Throughput', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.transactionThroughput, + 'transaction.type': transactionType, + 'transaction.name': transactionName, + }, + }, + { + title: 'Failure rate', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.transactionFailureRate, + 'transaction.type': transactionType, + 'transaction.name': transactionName, + }, + }, + { + title: 'Error events', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.errorEventRate, + }, + }, + ], + }, + }); + + return res + .filter((timeseries) => timeseries.changes.length > 0) + .map((timeseries) => ({ + title: timeseries.stat.title, + grouping: timeseries.id, + changes: timeseries.changes, + })); +} + +export async function getExitSpanChangePoints({ + apmEventClient, + alertStartedAt, + serviceName, + serviceEnvironment, +}: { + apmEventClient: APMEventClient; + alertStartedAt: string; + serviceName: string | undefined; + serviceEnvironment: string | undefined; +}): Promise { + if (!serviceName) { + return []; + } + + const res = await getApmTimeseries({ + apmEventClient, + arguments: { + start: moment(alertStartedAt).subtract(30, 'minute').toISOString(), + end: alertStartedAt, + stats: [ + { + title: 'Exit span latency', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.exitSpanLatency, + }, + }, + { + title: 'Exit span failure rate', + 'service.name': serviceName, + 'service.environment': serviceEnvironment, + timeseries: { + name: ApmTimeseriesType.exitSpanFailureRate, + }, + }, + ], + }, + }); + + return res + .filter((timeseries) => timeseries.changes.length > 0) + .map((timeseries) => { + return { + title: timeseries.stat.title, + grouping: timeseries.id, + changes: timeseries.changes, + }; + }); +} diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts index c842512507bec..990b63f412f76 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts @@ -31,7 +31,7 @@ export async function getLogCategories({ arguments: args, }: { esClient: ElasticsearchClient; - coreContext: CoreRequestHandlerContext; + coreContext: Pick; arguments: { start: string; end: string; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_alert_details_context_handler.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_alert_details_context_handler.ts new file mode 100644 index 0000000000000..cd1a56d56f45e --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_alert_details_context_handler.ts @@ -0,0 +1,85 @@ +/* + * 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 { Logger } from '@kbn/core/server'; +import { + AlertDetailsContextualInsightsHandlerQuery, + AlertDetailsContextualInsightsRequestContext, +} from '@kbn/observability-plugin/server/services'; +import { getApmAlertsClient } from '../../../lib/helpers/get_apm_alerts_client'; +import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client'; +import { getMlClient } from '../../../lib/helpers/get_ml_client'; +import { getRandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { getObservabilityAlertDetailsContext } from '.'; +import { APMRouteHandlerResources } from '../../apm_routes/register_apm_server_routes'; + +export const getAlertDetailsContextHandler = ( + resourcePlugins: APMRouteHandlerResources['plugins'], + logger: Logger +) => { + return async ( + requestContext: AlertDetailsContextualInsightsRequestContext, + query: AlertDetailsContextualInsightsHandlerQuery + ) => { + const resources = { + getApmIndices: async () => { + const coreContext = await requestContext.core; + return resourcePlugins.apmDataAccess.setup.getApmIndices(coreContext.savedObjects.client); + }, + request: requestContext.request, + params: { query: { _inspect: false } }, + plugins: resourcePlugins, + context: { + core: requestContext.core, + licensing: requestContext.licensing, + alerting: resourcePlugins.alerting!.start().then((startContract) => { + return { + getRulesClient() { + return startContract.getRulesClientWithRequest(requestContext.request); + }, + }; + }), + rac: resourcePlugins.ruleRegistry.start().then((startContract) => { + return { + getAlertsClient() { + return startContract.getRacClientWithRequest(requestContext.request); + }, + }; + }), + }, + }; + + const [apmEventClient, annotationsClient, apmAlertsClient, coreContext, mlClient] = + await Promise.all([ + getApmEventClient(resources), + resourcePlugins.observability.setup.getScopedAnnotationsClient( + resources.context, + requestContext.request + ), + getApmAlertsClient(resources), + requestContext.core, + getMlClient(resources), + getRandomSampler({ + security: resourcePlugins.security, + probability: 1, + request: requestContext.request, + }), + ]); + const esClient = coreContext.elasticsearch.client.asCurrentUser; + + return getObservabilityAlertDetailsContext({ + coreContext, + apmEventClient, + annotationsClient, + apmAlertsClient, + mlClient, + esClient, + query, + logger, + }); + }; +}; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_apm_alert_details_context_prompt.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_apm_alert_details_context_prompt.ts new file mode 100644 index 0000000000000..4a28a0460ebbd --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_apm_alert_details_context_prompt.ts @@ -0,0 +1,85 @@ +/* + * 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 { isEmpty } from 'lodash'; +import { AlertDetailsContextualInsight } from '@kbn/observability-plugin/server/services'; +import { APMDownstreamDependency } from '../get_apm_downstream_dependencies'; +import { ServiceSummary } from '../get_apm_service_summary'; +import { LogCategories } from '../get_log_categories'; +import { ApmAnomalies } from '../get_apm_service_summary/get_anomalies'; +import { ChangePointGrouping } from '../get_changepoints'; + +export function getApmAlertDetailsContextPrompt({ + serviceName, + serviceEnvironment, + serviceSummary, + downstreamDependencies, + logCategories, + serviceChangePoints, + exitSpanChangePoints, + anomalies, +}: { + serviceName?: string; + serviceEnvironment?: string; + serviceSummary?: ServiceSummary; + downstreamDependencies?: APMDownstreamDependency[]; + logCategories: LogCategories; + serviceChangePoints?: ChangePointGrouping[]; + exitSpanChangePoints?: ChangePointGrouping[]; + anomalies?: ApmAnomalies; +}): AlertDetailsContextualInsight[] { + const prompt: AlertDetailsContextualInsight[] = []; + if (!isEmpty(serviceSummary)) { + prompt.push({ + key: 'serviceSummary', + description: 'Metadata for the service where the alert occurred', + data: serviceSummary, + }); + } + + if (!isEmpty(downstreamDependencies)) { + prompt.push({ + key: 'downstreamDependencies', + description: `Downstream dependencies from the service "${serviceName}". Problems in these services can negatively affect the performance of "${serviceName}"`, + data: downstreamDependencies, + }); + } + + if (!isEmpty(serviceChangePoints)) { + prompt.push({ + key: 'serviceChangePoints', + description: `Significant change points for "${serviceName}". Use this to spot dips and spikes in throughput, latency and failure rate`, + data: serviceChangePoints, + }); + } + + if (!isEmpty(exitSpanChangePoints)) { + prompt.push({ + key: 'exitSpanChangePoints', + description: `Significant change points for the dependencies of "${serviceName}". Use this to spot dips or spikes in throughput, latency and failure rate for downstream dependencies`, + data: exitSpanChangePoints, + }); + } + + if (!isEmpty(logCategories)) { + prompt.push({ + key: 'logCategories', + description: `Log events occurring around the time of the alert`, + data: logCategories, + }); + } + + if (!isEmpty(anomalies)) { + prompt.push({ + key: 'anomalies', + description: `Anomalies for services running in the environment "${serviceEnvironment}"`, + data: anomalies, + }); + } + + return prompt; +} diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts index 953b49890a521..22679dd55ded0 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts @@ -12,12 +12,12 @@ import { rangeQuery, typedSearch } from '@kbn/observability-plugin/server/utils/ import * as t from 'io-ts'; import moment from 'moment'; import { ESSearchRequest } from '@kbn/es-types'; +import { observabilityAlertDetailsContextRt } from '@kbn/observability-plugin/server/services'; import { ApmDocumentType } from '../../../../common/document_type'; import { APMEventClient, APMEventESSearchRequest, } from '../../../lib/helpers/create_es_client/create_apm_event_client'; -import { observabilityAlertDetailsContextRt } from '.'; import { RollupInterval } from '../../../../common/rollup'; export async function getContainerIdFromSignals({ @@ -28,7 +28,7 @@ export async function getContainerIdFromSignals({ }: { query: t.TypeOf; esClient: ElasticsearchClient; - coreContext: CoreRequestHandlerContext; + coreContext: Pick; apmEventClient: APMEventClient; }) { if (query['container.id']) { @@ -76,7 +76,7 @@ async function getContainerIdFromLogs({ }: { params: ESSearchRequest['body']; esClient: ElasticsearchClient; - coreContext: CoreRequestHandlerContext; + coreContext: Pick; }) { const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); const res = await typedSearch<{ container: { id: string } }, any>(esClient, { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts index 3f79178b76d19..bd62b998bee99 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts @@ -12,12 +12,12 @@ import { rangeQuery, termQuery, typedSearch } from '@kbn/observability-plugin/se import * as t from 'io-ts'; import moment from 'moment'; import { ESSearchRequest } from '@kbn/es-types'; +import { observabilityAlertDetailsContextRt } from '@kbn/observability-plugin/server/services'; import { ApmDocumentType } from '../../../../common/document_type'; import { APMEventClient, APMEventESSearchRequest, } from '../../../lib/helpers/create_es_client/create_apm_event_client'; -import { observabilityAlertDetailsContextRt } from '.'; import { RollupInterval } from '../../../../common/rollup'; export async function getServiceNameFromSignals({ @@ -28,7 +28,7 @@ export async function getServiceNameFromSignals({ }: { query: t.TypeOf; esClient: ElasticsearchClient; - coreContext: CoreRequestHandlerContext; + coreContext: Pick; apmEventClient: APMEventClient; }) { if (query['service.name']) { @@ -85,7 +85,7 @@ async function getServiceNameFromLogs({ }: { params: ESSearchRequest['body']; esClient: ElasticsearchClient; - coreContext: CoreRequestHandlerContext; + coreContext: Pick; }) { const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); const res = await typedSearch<{ service: { name: string } }, any>(esClient, { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts index 0b76089d1e1c5..d6022876c9f3b 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts @@ -8,37 +8,22 @@ import type { ScopedAnnotationsClient } from '@kbn/observability-plugin/server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import type { CoreRequestHandlerContext, Logger } from '@kbn/core/server'; +import { + AlertDetailsContextualInsight, + AlertDetailsContextualInsightsHandlerQuery, +} from '@kbn/observability-plugin/server/services'; import moment from 'moment'; -import * as t from 'io-ts'; -import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; import type { MlClient } from '../../../lib/helpers/get_ml_client'; import type { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import type { ApmAlertsClient } from '../../../lib/helpers/get_apm_alerts_client'; import { getApmServiceSummary } from '../get_apm_service_summary'; import { getAssistantDownstreamDependencies } from '../get_apm_downstream_dependencies'; import { getLogCategories } from '../get_log_categories'; -import { ApmTimeseriesType, getApmTimeseries } from '../get_apm_timeseries'; import { getAnomalies } from '../get_apm_service_summary/get_anomalies'; import { getServiceNameFromSignals } from './get_service_name_from_signals'; import { getContainerIdFromSignals } from './get_container_id_from_signals'; - -export const observabilityAlertDetailsContextRt = t.intersection([ - t.type({ - alert_started_at: t.string, - }), - t.partial({ - // apm fields - 'service.name': t.string, - 'service.environment': t.string, - 'transaction.type': t.string, - 'transaction.name': t.string, - - // infrastructure fields - 'host.name': t.string, - 'container.id': t.string, - 'kubernetes.pod.name': t.string, - }), -]); +import { getApmAlertDetailsContextPrompt } from './get_apm_alert_details_context_prompt'; +import { getExitSpanChangePoints, getServiceChangePoints } from '../get_changepoints'; export async function getObservabilityAlertDetailsContext({ coreContext, @@ -50,15 +35,15 @@ export async function getObservabilityAlertDetailsContext({ mlClient, query, }: { - coreContext: CoreRequestHandlerContext; + coreContext: Pick; annotationsClient?: ScopedAnnotationsClient; apmAlertsClient: ApmAlertsClient; apmEventClient: APMEventClient; esClient: ElasticsearchClient; logger: Logger; mlClient?: MlClient; - query: t.TypeOf; -}) { + query: AlertDetailsContextualInsightsHandlerQuery; +}): Promise { const alertStartedAt = query.alert_started_at; const serviceEnvironment = query['service.environment']; const hostName = query['host.name']; @@ -182,141 +167,14 @@ export async function getObservabilityAlertDetailsContext({ anomaliesPromise, ]); - return { + return getApmAlertDetailsContextPrompt({ + serviceName, + serviceEnvironment, serviceSummary, downstreamDependencies, logCategories, serviceChangePoints, exitSpanChangePoints, anomalies, - }; -} - -async function getServiceChangePoints({ - apmEventClient, - alertStartedAt, - serviceName, - serviceEnvironment, - transactionType, - transactionName, -}: { - apmEventClient: APMEventClient; - alertStartedAt: string; - serviceName: string | undefined; - serviceEnvironment: string | undefined; - transactionType: string | undefined; - transactionName: string | undefined; -}) { - if (!serviceName) { - return []; - } - - const res = await getApmTimeseries({ - apmEventClient, - arguments: { - start: moment(alertStartedAt).subtract(12, 'hours').toISOString(), - end: alertStartedAt, - stats: [ - { - title: 'Latency', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.transactionLatency, - function: LatencyAggregationType.p95, - 'transaction.type': transactionType, - 'transaction.name': transactionName, - }, - }, - { - title: 'Throughput', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.transactionThroughput, - 'transaction.type': transactionType, - 'transaction.name': transactionName, - }, - }, - { - title: 'Failure rate', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.transactionFailureRate, - 'transaction.type': transactionType, - 'transaction.name': transactionName, - }, - }, - { - title: 'Error events', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.errorEventRate, - }, - }, - ], - }, }); - - return res - .filter((timeseries) => timeseries.changes.length > 0) - .map((timeseries) => ({ - title: timeseries.stat.title, - grouping: timeseries.id, - changes: timeseries.changes, - })); -} - -async function getExitSpanChangePoints({ - apmEventClient, - alertStartedAt, - serviceName, - serviceEnvironment, -}: { - apmEventClient: APMEventClient; - alertStartedAt: string; - serviceName: string | undefined; - serviceEnvironment: string | undefined; -}) { - if (!serviceName) { - return []; - } - - const res = await getApmTimeseries({ - apmEventClient, - arguments: { - start: moment(alertStartedAt).subtract(30, 'minute').toISOString(), - end: alertStartedAt, - stats: [ - { - title: 'Exit span latency', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.exitSpanLatency, - }, - }, - { - title: 'Exit span failure rate', - 'service.name': serviceName, - 'service.environment': serviceEnvironment, - timeseries: { - name: ApmTimeseriesType.exitSpanFailureRate, - }, - }, - ], - }, - }); - - return res - .filter((timeseries) => timeseries.changes.length > 0) - .map((timeseries) => { - return { - title: timeseries.stat.title, - grouping: timeseries.id, - changes: timeseries.changes, - }; - }); } diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts index a94b13b79577c..af3dfac613bd5 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts @@ -6,33 +6,26 @@ */ import * as t from 'io-ts'; import { omit } from 'lodash'; +import { + AlertDetailsContextualInsight, + observabilityAlertDetailsContextRt, +} from '@kbn/observability-plugin/server/services'; import { getApmAlertsClient } from '../../lib/helpers/get_apm_alerts_client'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { getMlClient } from '../../lib/helpers/get_ml_client'; import { getRandomSampler } from '../../lib/helpers/get_random_sampler'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; -import { - observabilityAlertDetailsContextRt, - getObservabilityAlertDetailsContext, -} from './get_observability_alert_details_context'; +import { getObservabilityAlertDetailsContext } from './get_observability_alert_details_context'; import { downstreamDependenciesRouteRt, getAssistantDownstreamDependencies, type APMDownstreamDependency, } from './get_apm_downstream_dependencies'; -import { type ServiceSummary } from './get_apm_service_summary'; -import { ApmAnomalies } from './get_apm_service_summary/get_anomalies'; -import { - getApmTimeseries, - getApmTimeseriesRt, - TimeseriesChangePoint, - type ApmTimeseries, -} from './get_apm_timeseries'; -import { LogCategories } from './get_log_categories'; +import { getApmTimeseries, getApmTimeseriesRt, type ApmTimeseries } from './get_apm_timeseries'; const getObservabilityAlertDetailsContextRoute = createApmServerRoute({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', options: { tags: ['access:apm'], }, @@ -40,22 +33,7 @@ const getObservabilityAlertDetailsContextRoute = createApmServerRoute({ params: t.type({ query: observabilityAlertDetailsContextRt, }), - handler: async ( - resources - ): Promise<{ - serviceSummary?: ServiceSummary; - downstreamDependencies?: APMDownstreamDependency[]; - logCategories?: LogCategories; - serviceChangePoints?: Array<{ - title: string; - changes: TimeseriesChangePoint[]; - }>; - exitSpanChangePoints?: Array<{ - title: string; - changes: TimeseriesChangePoint[]; - }>; - anomalies?: ApmAnomalies; - }> => { + handler: async (resources): Promise<{ context: AlertDetailsContextualInsight[] }> => { const { context, request, plugins, logger, params } = resources; const { query } = params; @@ -74,7 +52,7 @@ const getObservabilityAlertDetailsContextRoute = createApmServerRoute({ ]); const esClient = coreContext.elasticsearch.client.asCurrentUser; - return getObservabilityAlertDetailsContext({ + const obsAlertContext = await getObservabilityAlertDetailsContext({ coreContext, annotationsClient, apmAlertsClient, @@ -84,6 +62,8 @@ const getObservabilityAlertDetailsContextRoute = createApmServerRoute({ mlClient, query, }); + + return { context: obsAlertContext }; }, }); diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/alert_details_contextual_insights.tsx b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/alert_details_contextual_insights.tsx index 5b043e3ac8928..1de4b4a136919 100644 --- a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/alert_details_contextual_insights.tsx +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/alert_details_contextual_insights.tsx @@ -10,7 +10,6 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import dedent from 'dedent'; -import { isEmpty } from 'lodash'; import { useKibana } from '../../utils/kibana_react'; import { AlertData } from '../../hooks/use_fetch_alert_detail'; @@ -29,7 +28,9 @@ export function AlertDetailContextualInsights({ alert }: { alert: AlertData | nu } try { - const res = await http.get('/internal/apm/assistant/get_obs_alert_details_context', { + const { context } = await http.get<{ + context: Array<{ description: string; data: unknown }>; + }>('/internal/apm/assistant/alert_details_contextual_insights', { query: { alert_started_at: new Date(alert.formatted.start).toISOString(), @@ -46,60 +47,9 @@ export function AlertDetailContextualInsights({ alert }: { alert: AlertData | nu }, }); - const { - serviceSummary, - downstreamDependencies, - logCategories, - serviceChangePoints, - exitSpanChangePoints, - anomalies, - } = res as any; - - const serviceName = fields['service.name']; - const serviceEnvironment = fields['service.environment']; - - const obsAlertContext = `${ - !isEmpty(serviceSummary) - ? `Metadata for the service where the alert occurred: -${JSON.stringify(serviceSummary, null, 2)}` - : '' - } - - ${ - !isEmpty(downstreamDependencies) - ? `Downstream dependencies from the service "${serviceName}". Problems in these services can negatively affect the performance of "${serviceName}": -${JSON.stringify(downstreamDependencies, null, 2)}` - : '' - } - - ${ - !isEmpty(serviceChangePoints) - ? `Significant change points for "${serviceName}". Use this to spot dips and spikes in throughput, latency and failure rate: - ${JSON.stringify(serviceChangePoints, null, 2)}` - : '' - } - - ${ - !isEmpty(exitSpanChangePoints) - ? `Significant change points for the dependencies of "${serviceName}". Use this to spot dips or spikes in throughput, latency and failure rate for downstream dependencies: - ${JSON.stringify(exitSpanChangePoints, null, 2)}` - : '' - } - - ${ - !isEmpty(logCategories) - ? `Log events occurring around the time of the alert: - ${JSON.stringify(logCategories, null, 2)}` - : '' - } - - ${ - !isEmpty(anomalies) - ? `Anomalies for services running in the environment "${serviceEnvironment}": - ${anomalies}` - : '' - } - `; + const obsAlertContext = context + .map(({ description, data }) => `${description}:\n${JSON.stringify(data, null, 2)}`) + .join('\n\n'); return observabilityAIAssistant.getContextualInsightMessages({ message: `I'm looking at an alert and trying to understand why it was triggered`, diff --git a/x-pack/plugins/observability_solution/observability/server/plugin.ts b/x-pack/plugins/observability_solution/observability/server/plugin.ts index a9ae78ee146ae..fad3db3f5fd10 100644 --- a/x-pack/plugins/observability_solution/observability/server/plugin.ts +++ b/x-pack/plugins/observability_solution/observability/server/plugin.ts @@ -52,6 +52,7 @@ import { registerRuleTypes } from './lib/rules/register_rule_types'; import { getObservabilityServerRouteRepository } from './routes/get_global_observability_server_route_repository'; import { registerRoutes } from './routes/register_routes'; import { threshold } from './saved_objects/threshold'; +import { AlertDetailsContextualInsightsService } from './services'; import { uiSettings } from './ui_settings'; export type ObservabilityPluginSetup = ReturnType; @@ -99,6 +100,8 @@ export class ObservabilityPlugin implements Plugin { const logsExplorerLocator = plugins.share.url.locators.get(LOGS_EXPLORER_LOCATOR_ID); + const alertDetailsContextualInsightsService = new AlertDetailsContextualInsightsService(); + plugins.features.registerKibanaFeature({ id: casesFeatureId, name: i18n.translate('xpack.observability.featureRegistry.linkObservabilityTitle', { @@ -293,6 +296,9 @@ export class ObservabilityPlugin implements Plugin { }, spaces: pluginStart.spaces, ruleDataService, + assistant: { + alertDetailsContextualInsightsService, + }, getRulesClientWithRequest: pluginStart.alerting.getRulesClientWithRequest, }, logger: this.logger, @@ -312,6 +318,7 @@ export class ObservabilityPlugin implements Plugin { const api = await annotationsApiPromise; return api?.getScopedAnnotationsClient(...args); }, + alertDetailsContextualInsightsService, alertsLocator, }; } diff --git a/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts b/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts index 92980f20c4646..373e91d89a1c3 100644 --- a/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts +++ b/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts @@ -19,6 +19,7 @@ import axios from 'axios'; import * as t from 'io-ts'; import { ObservabilityConfig } from '..'; import { getHTTPResponseCode, ObservabilityError } from '../errors'; +import { AlertDetailsContextualInsightsService } from '../services'; import { ObservabilityRequestHandlerContext } from '../types'; import { AbstractObservabilityServerRouteRepository } from './types'; @@ -36,6 +37,9 @@ export interface RegisterRoutesDependencies { }; spaces?: SpacesPluginStart; ruleDataService: RuleDataPluginService; + assistant: { + alertDetailsContextualInsightsService: AlertDetailsContextualInsightsService; + }; getRulesClientWithRequest: (request: KibanaRequest) => RulesClientApi; } diff --git a/x-pack/plugins/observability_solution/observability/server/services/index.test.ts b/x-pack/plugins/observability_solution/observability/server/services/index.test.ts new file mode 100644 index 0000000000000..d0dcb08e9f31d --- /dev/null +++ b/x-pack/plugins/observability_solution/observability/server/services/index.test.ts @@ -0,0 +1,29 @@ +/* + * 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 { + AlertDetailsContextualInsightsHandlerQuery, + AlertDetailsContextualInsightsRequestContext, + AlertDetailsContextualInsightsService, +} from '.'; + +describe('AlertDetailsContextualInsightsService', () => { + it('concatenates context from registered handlers', async () => { + const service = new AlertDetailsContextualInsightsService(); + service.registerHandler(async () => [{ key: 'foo', description: 'foo', data: 'hello' }]); + service.registerHandler(async () => [{ key: 'bar', description: 'bar', data: 'hello' }]); + const context = await service.getAlertDetailsContext( + {} as AlertDetailsContextualInsightsRequestContext, + {} as AlertDetailsContextualInsightsHandlerQuery + ); + + expect(context).toEqual([ + { key: 'foo', description: 'foo', data: 'hello' }, + { key: 'bar', description: 'bar', data: 'hello' }, + ]); + }); +}); diff --git a/x-pack/plugins/observability_solution/observability/server/services/index.ts b/x-pack/plugins/observability_solution/observability/server/services/index.ts new file mode 100644 index 0000000000000..7c20d191440d6 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability/server/services/index.ts @@ -0,0 +1,87 @@ +/* + * 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 * as t from 'io-ts'; +import { + IScopedClusterClient, + IUiSettingsClient, + KibanaRequest, + SavedObjectsClientContract, +} from '@kbn/core/server'; +import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; +import { concat } from 'lodash'; + +export const observabilityAlertDetailsContextRt = t.intersection([ + t.type({ + alert_started_at: t.string, + }), + t.partial({ + // apm fields + 'service.name': t.string, + 'service.environment': t.string, + 'transaction.type': t.string, + 'transaction.name': t.string, + + // infrastructure fields + 'host.name': t.string, + 'container.id': t.string, + 'kubernetes.pod.name': t.string, + }), +]); + +export type AlertDetailsContextualInsightsHandlerQuery = t.TypeOf< + typeof observabilityAlertDetailsContextRt +>; + +export interface AlertDetailsContextualInsight { + key: string; + description: string; + data: unknown; +} + +export interface AlertDetailsContextualInsightsRequestContext { + request: KibanaRequest; + core: Promise<{ + elasticsearch: { + client: IScopedClusterClient; + }; + uiSettings: { + client: IUiSettingsClient; + globalClient: IUiSettingsClient; + }; + savedObjects: { + client: SavedObjectsClientContract; + }; + }>; + licensing: Promise; +} +type AlertDetailsContextualInsightsHandler = ( + context: AlertDetailsContextualInsightsRequestContext, + query: AlertDetailsContextualInsightsHandlerQuery +) => Promise; + +export class AlertDetailsContextualInsightsService { + private handlers: AlertDetailsContextualInsightsHandler[] = []; + + constructor() {} + + registerHandler(handler: AlertDetailsContextualInsightsHandler) { + this.handlers.push(handler); + } + + async getAlertDetailsContext( + context: AlertDetailsContextualInsightsRequestContext, + query: AlertDetailsContextualInsightsHandlerQuery + ): Promise { + if (this.handlers.length === 0) return []; + + return Promise.all(this.handlers.map((handler) => handler(context, query))).then((results) => { + const [head, ...rest] = results; + return concat(head, ...rest); + }); + } +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts index c63a4a902b337..c0b37b7142a83 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts @@ -40,6 +40,7 @@ export type ObservabilityAIAssistantRequestHandlerContext = Omit< }; uiSettings: { client: IUiSettingsClient; + globalClient: IUiSettingsClient; }; savedObjects: { client: SavedObjectsClientContract; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc index b64d31e3f13b9..17a9812631e39 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc @@ -11,6 +11,7 @@ "aiAssistantManagementSelection", "observabilityAIAssistant", "observabilityShared", + "observability", "actions", "data", "dataViews", diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/plugin.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/plugin.ts index 903c3c0c26826..63e06818a2b70 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/plugin.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/plugin.ts @@ -96,6 +96,7 @@ export class ObservabilityAIAssistantAppPlugin }, uiSettings: { client: coreStart.uiSettings.asScopedToClient(savedObjectsClient), + globalClient: coreStart.uiSettings.globalAsScopedToClient(savedObjectsClient), }, savedObjects: { client: savedObjectsClient, @@ -113,7 +114,12 @@ export class ObservabilityAIAssistantAppPlugin }; }; - plugins.actions.registerType(getObsAIAssistantConnectorType(initResources)); + plugins.actions.registerType( + getObsAIAssistantConnectorType( + initResources, + plugins.observability.alertDetailsContextualInsightsService + ) + ); plugins.alerting.registerConnectorAdapter(getObsAIAssistantConnectorAdapter()); return {}; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.test.ts index 190ce8c9ef95c..479ffeaa40f4f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.test.ts @@ -16,6 +16,7 @@ import { } from '.'; import { Observable } from 'rxjs'; import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; +import { AlertDetailsContextualInsightsService } from '@kbn/observability-plugin/server/services'; describe('observabilityAIAssistant rule_connector', () => { describe('getObsAIAssistantConnectorAdapter', () => { @@ -56,7 +57,10 @@ describe('observabilityAIAssistant rule_connector', () => { const initResources = jest .fn() .mockResolvedValue({} as ObservabilityAIAssistantRouteHandlerResources); - const connectorType = getObsAIAssistantConnectorType(initResources); + const connectorType = getObsAIAssistantConnectorType( + initResources, + new AlertDetailsContextualInsightsService() + ); expect(connectorType.id).toEqual(OBSERVABILITY_AI_ASSISTANT_CONNECTOR_ID); expect(connectorType.isSystemActionType).toEqual(true); expect(connectorType.minimumLicenseRequired).toEqual('enterprise'); @@ -66,7 +70,10 @@ describe('observabilityAIAssistant rule_connector', () => { const initResources = jest .fn() .mockResolvedValue({} as ObservabilityAIAssistantRouteHandlerResources); - const connectorType = getObsAIAssistantConnectorType(initResources); + const connectorType = getObsAIAssistantConnectorType( + initResources, + new AlertDetailsContextualInsightsService() + ); const result = await connectorType.executor({ actionId: 'observability-ai-assistant', request: getFakeKibanaRequest({ id: 'foo', api_key: 'bar' }), @@ -106,7 +113,10 @@ describe('observabilityAIAssistant rule_connector', () => { }, } as unknown as ObservabilityAIAssistantRouteHandlerResources); - const connectorType = getObsAIAssistantConnectorType(initResources); + const connectorType = getObsAIAssistantConnectorType( + initResources, + new AlertDetailsContextualInsightsService() + ); const result = await connectorType.executor({ actionId: 'observability-ai-assistant', request: getFakeKibanaRequest({ id: 'foo', api_key: 'bar' }), @@ -142,6 +152,26 @@ describe('observabilityAIAssistant rule_connector', () => { content: 'hello', }, }, + { + '@timestamp': expect.any(String), + message: { + role: MessageRole.Assistant, + content: '', + function_call: { + name: 'get_alerts_context', + arguments: JSON.stringify({}), + trigger: MessageRole.Assistant as const, + }, + }, + }, + { + '@timestamp': expect.any(String), + message: { + role: MessageRole.User, + name: 'get_alerts_context', + content: expect.any(String), + }, + }, { '@timestamp': expect.any(String), message: { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.ts index b46fec93d1dd1..c6b8b56b45a87 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/rule_connector/index.ts @@ -6,6 +6,8 @@ */ import { filter } from 'rxjs'; +import { get } from 'lodash'; +import dedent from 'dedent'; import { i18n } from '@kbn/i18n'; import { schema, TypeOf } from '@kbn/config-schema'; import { KibanaRequest, Logger } from '@kbn/core/server'; @@ -32,6 +34,7 @@ import { } from '@kbn/observability-ai-assistant-plugin/common'; import { concatenateChatCompletionChunks } from '@kbn/observability-ai-assistant-plugin/common/utils/concatenate_chat_completion_chunks'; import { CompatibleJSONSchema } from '@kbn/observability-ai-assistant-plugin/common/functions/types'; +import { AlertDetailsContextualInsightsService } from '@kbn/observability-plugin/server/services'; import { getSystemMessageFromInstructions } from '@kbn/observability-ai-assistant-plugin/server/service/util/get_system_message_from_instructions'; import { convertSchemaToOpenApi } from './convert_schema_to_open_api'; import { OBSERVABILITY_AI_ASSISTANT_CONNECTOR_ID } from '../../common/rule_connector'; @@ -87,7 +90,8 @@ export type ObsAIAssistantConnectorTypeExecutorOptions = ConnectorTypeExecutorOp >; export function getObsAIAssistantConnectorType( - initResources: (request: KibanaRequest) => Promise + initResources: (request: KibanaRequest) => Promise, + alertDetailsContextService: AlertDetailsContextualInsightsService ): ObsAIAssistantConnectorType { return { id: OBSERVABILITY_AI_ASSISTANT_CONNECTOR_ID, @@ -112,7 +116,7 @@ export function getObsAIAssistantConnectorType( }, renderParameterTemplates, executor(options) { - return executor(options, initResources); + return executor(options, initResources, alertDetailsContextService); }, }; } @@ -132,7 +136,8 @@ function renderParameterTemplates( async function executor( execOptions: ObsAIAssistantConnectorTypeExecutorOptions, - initResources: (request: KibanaRequest) => Promise + initResources: (request: KibanaRequest) => Promise, + alertDetailsContextService: AlertDetailsContextualInsightsService ): Promise> { const request = execOptions.request; const alerts = execOptions.params.alerts; @@ -172,9 +177,34 @@ async function executor( }); }); - const backgroundInstruction = getBackgroundProcessInstruction( + const backgroundInstruction = dedent( + `You are called as a background process because alerts have changed state. + As a background process you are not interacting with a user. Because of that DO NOT ask for user + input if tasked to execute actions. You can generate multiple responses in a row. + If available, include the link of the conversation at the end of your answer.` + ); + + const alertsContext = await getAlertsContext( execOptions.params.rule, - execOptions.params.alerts + execOptions.params.alerts, + async (alert: Record) => { + const prompt = await alertDetailsContextService.getAlertDetailsContext( + { + core: resources.context.core, + licensing: resources.context.licensing, + request: resources.request, + }, + { + alert_started_at: get(alert, 'kibana.alert.start'), + 'service.name': get(alert, 'service.name'), + 'service.environment': get(alert, 'service.environment'), + 'host.name': get(alert, 'host.name'), + } + ); + return prompt + .map(({ description, data }) => `${description}:\n${JSON.stringify(data, null, 2)}`) + .join('\n\n'); + } ); client @@ -206,6 +236,26 @@ async function executor( content: execOptions.params.message, }, }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.Assistant, + content: '', + function_call: { + name: 'get_alerts_context', + arguments: JSON.stringify({}), + trigger: MessageRole.Assistant as const, + }, + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.User, + name: 'get_alerts_context', + content: JSON.stringify({ context: alertsContext }), + }, + }, { '@timestamp': new Date().toISOString(), message: { @@ -268,23 +318,38 @@ export const getObsAIAssistantConnectorAdapter = (): ConnectorAdapter< }; }; -function getBackgroundProcessInstruction(rule: RuleType, alerts: AlertSummary) { - let instruction = `You are called as a background process because the following alerts have changed state for the rule ${JSON.stringify( - rule +async function getAlertsContext( + rule: RuleType, + alerts: AlertSummary, + getAlertContext: (alert: Record) => Promise +): Promise { + const getAlertGroupDetails = async (alertGroup: Array>) => { + const formattedDetails = await Promise.all( + alertGroup.map(async (alert) => { + return `- ${JSON.stringify( + alert + )}. The following contextual information is available:\n${await getAlertContext(alert)}`; + }) + ).then((messages) => messages.join('\n')); + + return formattedDetails; + }; + + let details = `The following alerts have changed state for the rule ${JSON.stringify( + rule, + null, + 2 )}:\n`; if (alerts.new.length > 0) { - instruction += `- ${alerts.new.length} alerts have fired: ${JSON.stringify(alerts.new)}\n`; + details += `- ${alerts.new.length} alerts have fired:\n${await getAlertGroupDetails( + alerts.new + )}\n`; } if (alerts.recovered.length > 0) { - instruction += `- ${alerts.recovered.length} alerts have recovered: ${JSON.stringify( + details += `- ${alerts.recovered.length} alerts have recovered\n: ${await getAlertGroupDetails( alerts.recovered )}\n`; } - instruction += - ' As a background process you are not interacting with a user. Because of that DO NOT ask for user'; - instruction += - ' input if tasked to execute actions. You can generate multiple responses in a row.'; - instruction += ' If available, include the link of the conversation at the end of your answer.'; - return instruction; + return details; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts index 902774bacd800..680e5b2409b7c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts @@ -37,6 +37,7 @@ import type { } from '@kbn/task-manager-plugin/server'; import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; +import type { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ObservabilityAIAssistantAppServerStart {} @@ -67,6 +68,7 @@ export interface ObservabilityAIAssistantAppPluginSetupDependencies { features: FeaturesPluginSetup; taskManager: TaskManagerSetupContract; dataViews: DataViewsServerPluginSetup; + observability: ObservabilityPluginSetup; cloud?: CloudSetup; serverless?: ServerlessPluginSetup; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json index 5b32c8ce5aa7c..90c4f4d415142 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json @@ -68,6 +68,7 @@ "@kbn/serverless", "@kbn/task-manager-plugin", "@kbn/cloud-plugin", + "@kbn/observability-plugin" ], "exclude": ["target/**/*"] } diff --git a/x-pack/test/apm_api_integration/tests/assistant/obs_alert_details_context.spec.ts b/x-pack/test/apm_api_integration/tests/assistant/obs_alert_details_context.spec.ts index fe9967683ec8d..5a98ec708bcf3 100644 --- a/x-pack/test/apm_api_integration/tests/assistant/obs_alert_details_context.spec.ts +++ b/x-pack/test/apm_api_integration/tests/assistant/obs_alert_details_context.spec.ts @@ -8,6 +8,7 @@ import moment from 'moment'; import { log, apm, generateShortId, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; +import { LogCategories } from '@kbn/apm-plugin/server/routes/assistant_functions/get_log_categories'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { SupertestReturnType } from '../../common/apm_api_supertest'; @@ -26,10 +27,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { const range = timerange(start, end); describe('when no traces or logs are available', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -39,11 +40,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns nothing', () => { - expect(response.body).to.eql({ - serviceChangePoints: [], - exitSpanChangePoints: [], - anomalies: [], - }); + expect(response.body.context).to.eql([]); }); }); @@ -61,10 +58,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when no params are specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -73,26 +70,21 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); }); - it('returns no service summary', async () => { - expect(response.body.serviceSummary).to.be(undefined); - }); - - it('returns no downstream dependencies', async () => { - expect(response.body.downstreamDependencies ?? []).to.eql([]); - }); - - it('returns 1 log category', async () => { - expect(response.body.logCategories?.map(({ errorCategory }) => errorCategory)).to.eql([ - 'Error message from container my-container-a', - ]); + it('returns only 1 log category', async () => { + expect(response.body.context).to.have.length(1); + expect( + (response.body.context[0]?.data as LogCategories)?.map( + ({ errorCategory }: { errorCategory: string }) => errorCategory + ) + ).to.eql(['Error message from container my-container-a']); }); }); describe('when service name is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -103,7 +95,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns service summary', () => { - expect(response.body.serviceSummary).to.eql({ + const serviceSummary = response.body.context.find( + ({ key }) => key === 'serviceSummary' + ); + expect(serviceSummary?.data).to.eql({ 'service.name': 'Backend', 'service.environment': ['production'], 'agent.name': 'java', @@ -117,7 +112,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns downstream dependencies', async () => { - expect(response.body.downstreamDependencies).to.eql([ + const downstreamDependencies = response.body.context.find( + ({ key }) => key === 'downstreamDependencies' + ); + expect(downstreamDependencies?.data).to.eql([ { 'span.destination.service.resource': 'elasticsearch', 'span.type': 'db', @@ -127,9 +125,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns log categories', () => { - expect(response.body.logCategories).to.have.length(1); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); - const logCategory = response.body.logCategories?.[0]; + const logCategory = (logCategories?.data as LogCategories)?.[0]; expect(logCategory?.sampleMessage).to.match( /Error message #\d{16} from container my-container-a/ ); @@ -139,10 +138,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when container id is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -153,7 +152,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns service summary', () => { - expect(response.body.serviceSummary).to.eql({ + const serviceSummary = response.body.context.find( + ({ key }) => key === 'serviceSummary' + ); + expect(serviceSummary?.data).to.eql({ 'service.name': 'Backend', 'service.environment': ['production'], 'agent.name': 'java', @@ -167,7 +169,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns downstream dependencies', async () => { - expect(response.body.downstreamDependencies).to.eql([ + const downstreamDependencies = response.body.context.find( + ({ key }) => key === 'downstreamDependencies' + ); + expect(downstreamDependencies?.data).to.eql([ { 'span.destination.service.resource': 'elasticsearch', 'span.type': 'db', @@ -177,9 +182,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns log categories', () => { - expect(response.body.logCategories).to.have.length(1); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); - const logCategory = response.body.logCategories?.[0]; + const logCategory = (logCategories?.data as LogCategories)?.[0]; expect(logCategory?.sampleMessage).to.match( /Error message #\d{16} from container my-container-a/ ); @@ -189,10 +195,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when non-existing container id is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -203,20 +209,15 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns nothing', () => { - expect(response.body).to.eql({ - logCategories: [], - serviceChangePoints: [], - exitSpanChangePoints: [], - anomalies: [], - }); + expect(response.body.context).to.eql([]); }); }); describe('when non-existing service.name is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -227,7 +228,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns empty service summary', () => { - expect(response.body.serviceSummary).to.eql({ + const serviceSummary = response.body.context.find( + ({ key }) => key === 'serviceSummary' + ); + expect(serviceSummary?.data).to.eql({ 'service.name': 'non-existing-service', 'service.environment': [], instances: 1, @@ -238,11 +242,15 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns no downstream dependencies', async () => { - expect(response.body.downstreamDependencies).to.eql([]); + const downstreamDependencies = response.body.context.find( + ({ key }) => key === 'downstreamDependencies' + ); + expect(downstreamDependencies).to.eql(undefined); }); it('returns log categories', () => { - expect(response.body.logCategories).to.have.length(1); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); }); }); }); @@ -276,10 +284,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when no params are specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -289,22 +297,27 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns no service summary', async () => { - expect(response.body.serviceSummary).to.be(undefined); + const serviceSummary = response.body.context.find( + ({ key }) => key === 'serviceSummary' + ); + expect(serviceSummary).to.be(undefined); }); it('returns 1 log category', async () => { - expect(response.body.logCategories?.map(({ errorCategory }) => errorCategory)).to.eql([ - 'Error message from service', - 'Error message from container my-container-c', - ]); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect( + (logCategories?.data as LogCategories)?.map( + ({ errorCategory }: { errorCategory: string }) => errorCategory + ) + ).to.eql(['Error message from service', 'Error message from container my-container-c']); }); }); describe('when service name is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -315,9 +328,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns log categories', () => { - expect(response.body.logCategories).to.have.length(1); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); - const logCategory = response.body.logCategories?.[0]; + const logCategory = (logCategories?.data as LogCategories)?.[0]; expect(logCategory?.sampleMessage).to.match( /Error message #\d{16} from service Backend/ ); @@ -327,10 +341,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when container id is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -341,9 +355,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns log categories', () => { - expect(response.body.logCategories).to.have.length(1); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); - const logCategory = response.body.logCategories?.[0]; + const logCategory = (logCategories?.data as LogCategories)?.[0]; expect(logCategory?.sampleMessage).to.match( /Error message #\d{16} from service Backend/ ); @@ -353,10 +368,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when non-existing service.name is specified', async () => { - let response: SupertestReturnType<'GET /internal/apm/assistant/get_obs_alert_details_context'>; + let response: SupertestReturnType<'GET /internal/apm/assistant/alert_details_contextual_insights'>; before(async () => { response = await apmApiClient.writeUser({ - endpoint: 'GET /internal/apm/assistant/get_obs_alert_details_context', + endpoint: 'GET /internal/apm/assistant/alert_details_contextual_insights', params: { query: { alert_started_at: new Date(end).toISOString(), @@ -367,7 +382,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns empty service summary', () => { - expect(response.body.serviceSummary).to.eql({ + const serviceSummary = response.body.context.find( + ({ key }) => key === 'serviceSummary' + ); + expect(serviceSummary?.data).to.eql({ 'service.name': 'non-existing-service', 'service.environment': [], instances: 1, @@ -378,9 +396,14 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('does not return log categories', () => { - expect(response.body.logCategories?.map(({ errorCategory }) => errorCategory)).to.eql([ - 'Error message from container my-container-c', - ]); + const logCategories = response.body.context.find(({ key }) => key === 'logCategories'); + expect(logCategories?.data).to.have.length(1); + + expect( + (logCategories?.data as LogCategories)?.map( + ({ errorCategory }: { errorCategory: string }) => errorCategory + ) + ).to.eql(['Error message from container my-container-c']); }); }); }); From 6dab9ae6fef046dba83cb0c6592acf302350829e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 09:14:39 -0700 Subject: [PATCH 104/104] Update dependency elastic-apm-node to ^4.5.3 (main) (#182236) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ed0f5a514f224..ee618ed1e6690 100644 --- a/package.json +++ b/package.json @@ -990,7 +990,7 @@ "deepmerge": "^4.2.2", "del": "^6.1.0", "diff": "^5.1.0", - "elastic-apm-node": "^4.5.2", + "elastic-apm-node": "^4.5.3", "email-addresses": "^5.0.0", "eventsource-parser": "^1.1.1", "execa": "^5.1.1", diff --git a/yarn.lock b/yarn.lock index f748ddf3048d7..73652d1074cd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15918,10 +15918,10 @@ elastic-apm-node@3.46.0: traverse "^0.6.6" unicode-byte-truncate "^1.0.0" -elastic-apm-node@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-4.5.2.tgz#7c4a9d77a891302f16e988a6ff4ade5563e805ec" - integrity sha512-m4hvI/1MpVlR5B8k6BOU7WzdFOXjYux/iRso6av6qqJhYKSbHKhF93ncatw4nXU1q88tu31gwB9CzA2/6F4hFQ== +elastic-apm-node@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-4.5.3.tgz#8015f1525f6cd45daef6a48a88d93dbaf5899212" + integrity sha512-FE+srHVTtvDp/SfY76yxSIupCU8Z30WuOx1Yf3plUXeyLuKqq9YRk6uX0Jleb1jfwG58lvabpeU0u9YmS1YdrA== dependencies: "@elastic/ecs-pino-format" "^1.5.0" "@opentelemetry/api" "^1.4.1"