From 91e84900033a021f9d1279b6c16c17c9df1274ce Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Mon, 27 Jan 2025 16:21:20 +0100 Subject: [PATCH] [StdPerf] Add onPageLoad event to alerts and alert details pages (#207089) ## Summary This PR adds StdPerf to the alerts page and alert details page only for the overview tab. |Page|Screenshot| |---|---| |Alerts page|![image](https://github.com/user-attachments/assets/4fe7aa75-b986-4b3c-90a9-4f55e2a21129)| |Alert details page|![image](https://github.com/user-attachments/assets/5662b171-2699-4a49-86e0-c89bb98800d2)| --- Resolves https://github.com/elastic/observability-dev/issues/3559 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../public/application/index.tsx | 11 +++++++---- .../alert_details/alert_details.test.tsx | 7 ++++++- .../pages/alert_details/alert_details.tsx | 8 ++++++++ .../public/pages/alerts/alerts.test.tsx | 19 +++++++++++++++++++ .../public/pages/alerts/alerts.tsx | 19 +++++++++++++++++++ .../plugins/observability/tsconfig.json | 3 ++- 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/x-pack/solutions/observability/plugins/observability/public/application/index.tsx b/x-pack/solutions/observability/plugins/observability/public/application/index.tsx index 54b8b4044e64e..e19e729f39053 100644 --- a/x-pack/solutions/observability/plugins/observability/public/application/index.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/application/index.tsx @@ -8,6 +8,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { PerformanceContextProvider } from '@kbn/ebt-tools'; import { i18n } from '@kbn/i18n'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { AppMountParameters, APP_WRAPPER_CLASS, CoreStart } from '@kbn/core/public'; @@ -111,10 +112,12 @@ export const renderApp = ({ - - - - + + + + + + diff --git a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.test.tsx b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.test.tsx index be62ae6377bc6..17b13cc6f140f 100644 --- a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.test.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.test.tsx @@ -6,6 +6,7 @@ */ import { casesPluginMock } from '@kbn/cases-plugin/public/mocks'; +import { usePerformanceContext } from '@kbn/ebt-tools'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import * as useUiSettingHook from '@kbn/kibana-react-plugin/public/ui_settings/use_ui_setting'; import { observabilityAIAssistantPluginMock } from '@kbn/observability-ai-assistant-plugin/public/mock'; @@ -61,6 +62,7 @@ const mockKibana = () => { basePath: { prepend: jest.fn(), }, + get: jest.fn().mockReturnValue({ alertContext: [] }), }, observabilityAIAssistant: mockObservabilityAIAssistant, theme: {}, @@ -82,7 +84,9 @@ jest.mock('../../hooks/use_fetch_rule', () => { }; }); jest.mock('@kbn/observability-shared-plugin/public'); +jest.mock('@kbn/ebt-tools'); +const usePerformanceContextMock = usePerformanceContext as jest.Mock; const useFetchAlertDetailMock = useFetchAlertDetail as jest.Mock; const useParamsMock = useParams as jest.Mock; const useLocationMock = useLocation as jest.Mock; @@ -90,8 +94,9 @@ const useHistoryMock = useHistory as jest.Mock; const useBreadcrumbsMock = useBreadcrumbs as jest.Mock; const TagsListMock = TagsList as jest.Mock; -const chance = new Chance(); +usePerformanceContextMock.mockReturnValue({ onPageReady: jest.fn() }); +const chance = new Chance(); const params = { alertId: chance.guid(), }; diff --git a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.tsx b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.tsx index 9403090b1e213..6b9a5cb3480a9 100644 --- a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/alert_details.tsx @@ -7,6 +7,7 @@ import React, { useEffect, useState } from 'react'; import { useHistory, useLocation, useParams } from 'react-router-dom'; +import { usePerformanceContext } from '@kbn/ebt-tools'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { @@ -95,6 +96,7 @@ export function AlertDetails() { uiSettings, serverless, } = useKibana().services; + const { onPageReady } = usePerformanceContext(); const { search } = useLocation(); const history = useHistory(); @@ -181,6 +183,12 @@ export function AlertDetails() { setAlertStatus(ALERT_STATUS_UNTRACKED); }; + useEffect(() => { + if (!isLoading && !!alertDetail && activeTabId === OVERVIEW_TAB_ID) { + onPageReady(); + } + }, [onPageReady, alertDetail, isLoading, activeTabId]); + if (isLoading) { return ; } diff --git a/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.test.tsx b/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.test.tsx index 33dc64f35ee31..0b5b57c6b5362 100644 --- a/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.test.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import { usePerformanceContext } from '@kbn/ebt-tools'; import { EuiThemeProvider as ThemeProvider } from '@elastic/eui'; import { MAINTENANCE_WINDOW_FEATURE_ID } from '@kbn/alerting-plugin/common/maintenance_window'; import { fetchActiveMaintenanceWindows } from '@kbn/alerts-ui-shared/src/maintenance_window_callout/api'; @@ -21,6 +22,7 @@ import { useLocation } from 'react-router-dom'; import * as dataContext from '../../hooks/use_has_data'; import * as pluginContext from '../../hooks/use_plugin_context'; import { ObservabilityPublicPluginsStart } from '../../plugin'; +import { useGetAvailableRulesWithDescriptions } from '../../hooks/use_get_available_rules_with_descriptions'; import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock'; import { kibanaStartMock } from '../../utils/kibana_react.mock'; import { AlertsPage } from './alerts'; @@ -54,6 +56,11 @@ jest.mock('../../utils/kibana_react', () => ({ const useLocationMock = useLocation as jest.Mock; +jest.mock('@kbn/ebt-tools'); + +const usePerformanceContextMock = usePerformanceContext as jest.Mock; +usePerformanceContextMock.mockReturnValue({ onPageReady: jest.fn() }); + jest.mock('@kbn/kibana-react-plugin/public', () => ({ __esModule: true, useKibana: jest.fn(() => mockUseKibanaReturnValue), @@ -110,6 +117,18 @@ jest.mock('../../hooks/use_has_data', () => ({ const { useTimeBuckets } = jest.requireMock('../../hooks/use_time_buckets'); const { useHasData } = jest.requireMock('../../hooks/use_has_data'); +jest.mock('../../hooks/use_get_available_rules_with_descriptions'); + +const ruleDescriptions = [ + { + id: 'observability.rules.custom_threshold', + name: 'Custom threshold', + description: 'Alert when any Observability data type reaches or exceeds a given value.', + }, +]; +const useGetAvailableRulesWithDescriptionsMock = useGetAvailableRulesWithDescriptions as jest.Mock; +useGetAvailableRulesWithDescriptionsMock.mockReturnValue(ruleDescriptions); + const queryClient = new QueryClient({ defaultOptions: { queries: { diff --git a/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.tsx b/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.tsx index 64013c1762f1a..4fe112028d57c 100644 --- a/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/pages/alerts/alerts.tsx @@ -9,8 +9,10 @@ import React, { useEffect, useMemo, useState } from 'react'; import { BrushEndListener, XYBrushEvent } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { BoolQuery, Filter } from '@kbn/es-query'; +import { usePerformanceContext } from '@kbn/ebt-tools'; import { i18n } from '@kbn/i18n'; import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public'; +import type { TableUpdateHandlerArgs } from '@kbn/triggers-actions-ui-plugin/public/types'; import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public'; import { MaintenanceWindowCallout } from '@kbn/alerts-ui-shared'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; @@ -77,6 +79,7 @@ function InternalAlertsPage() { }, uiSettings, } = kibanaServices; + const { onPageReady } = usePerformanceContext(); const { toasts } = notifications; const { query: { @@ -94,6 +97,21 @@ function InternalAlertsPage() { const ruleTypesWithDescriptions = useGetAvailableRulesWithDescriptions(); + const onUpdate = ({ isLoading, totalCount }: TableUpdateHandlerArgs) => { + if (!isLoading) { + onPageReady({ + customMetrics: { + key1: 'total_alert_count', + value1: totalCount, + }, + meta: { + rangeFrom: alertSearchBarStateProps.rangeFrom, + rangeTo: alertSearchBarStateProps.rangeTo, + }, + }); + } + }; + useEffect(() => { return setScreenContext?.({ data: ruleTypesWithDescriptions.map((rule) => ({ @@ -299,6 +317,7 @@ function InternalAlertsPage() { initialPageSize={ALERTS_PER_PAGE} cellContext={{ observabilityRuleTypeRegistry }} alertsTableConfigurationRegistry={alertsTableConfigurationRegistry} + onUpdate={onUpdate} /> ); }} diff --git a/x-pack/solutions/observability/plugins/observability/tsconfig.json b/x-pack/solutions/observability/plugins/observability/tsconfig.json index 0d8d34ed76377..d78e468013be7 100644 --- a/x-pack/solutions/observability/plugins/observability/tsconfig.json +++ b/x-pack/solutions/observability/plugins/observability/tsconfig.json @@ -113,7 +113,8 @@ "@kbn/logging-mocks", "@kbn/response-ops-rule-form", "@kbn/streams-plugin", - "@kbn/data-service" + "@kbn/data-service", + "@kbn/ebt-tools" ], "exclude": ["target/**/*"] }