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 f1674a12b77c6..4c2a6d0058edc 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 @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import React, { FC } from 'react'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; diff --git a/x-pack/plugins/ml/public/application/routing/use_active_route.ts b/x-pack/plugins/ml/public/application/routing/use_active_route.ts index 925db8185c379..9183e45c3d0ae 100644 --- a/x-pack/plugins/ml/public/application/routing/use_active_route.ts +++ b/x-pack/plugins/ml/public/application/routing/use_active_route.ts @@ -8,11 +8,21 @@ import { useLocation, useRouteMatch } from 'react-router-dom'; import { keyBy } from 'lodash'; import { useMemo } from 'react'; +import { useExecutionContext } from '@kbn/kibana-react-plugin/public'; +import { useMlKibana } from '../contexts/kibana'; import type { MlRoute } from './router'; +/** + * Provides an active route of the ML app. + * @param routesList + */ export const useActiveRoute = (routesList: MlRoute[]): MlRoute => { const { pathname } = useLocation(); + const { + services: { executionContext }, + } = useMlKibana(); + /** * Temp fix for routes with params. */ @@ -30,8 +40,14 @@ export const useActiveRoute = (routesList: MlRoute[]): MlRoute => { } // Remove trailing slash from the pathname const pathnameKey = pathname.replace(/\/$/, ''); - return routesMap[pathnameKey]; + return routesMap[pathnameKey] ?? routesMap['/overview']; }, [pathname]); - return activeRoute ?? routesMap['/overview']; + useExecutionContext(executionContext, { + name: 'Machine Learning', + type: 'application', + page: activeRoute?.path, + }); + + return activeRoute; }; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx index 9f31f5777f9de..85350629263e4 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx @@ -11,6 +11,7 @@ import { Observable } from 'rxjs'; import { FormattedMessage } from '@kbn/i18n-react'; import { throttle } from 'lodash'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; +import { useEmbeddableExecutionContext } from '../common/use_embeddable_execution_context'; import { useAnomalyChartsInputResolver } from './use_anomaly_charts_input_resolver'; import type { IAnomalyChartsEmbeddable } from './anomaly_charts_embeddable'; import type { @@ -27,6 +28,7 @@ import { ANOMALY_THRESHOLD } from '../../../common'; import { TimeBuckets } from '../../application/util/time_buckets'; import { EXPLORER_ENTITY_FIELD_SELECTION_TRIGGER } from '../../ui_actions/triggers'; import { MlLocatorParams } from '../../../common/types/locator'; +import { ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE } from '..'; const RESIZE_THROTTLE_TIME_MS = 500; @@ -55,6 +57,13 @@ export const EmbeddableAnomalyChartsContainer: FC { + useEmbeddableExecutionContext( + services[0].executionContext, + embeddableInput, + ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE, + id + ); + const [chartWidth, setChartWidth] = useState(0); const [severity, setSeverity] = useState( optionValueToThreshold( diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx index 06c400481491a..c354057d971bb 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx @@ -11,6 +11,7 @@ import { Observable } from 'rxjs'; import { CoreStart } from '@kbn/core/public'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useEmbeddableExecutionContext } from '../common/use_embeddable_execution_context'; import { IAnomalySwimlaneEmbeddable } from './anomaly_swimlane_embeddable'; import { useSwimlaneInputResolver } from './swimlane_input_resolver'; import { SwimlaneType } from '../../application/explorer/explorer_constants'; @@ -22,6 +23,7 @@ import { AppStateSelectedCells } from '../../application/explorer/explorer_utils import { MlDependencies } from '../../application/app'; import { SWIM_LANE_SELECTION_TRIGGER } from '../../ui_actions'; import { + ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, AnomalySwimlaneEmbeddableInput, AnomalySwimlaneEmbeddableOutput, AnomalySwimlaneServices, @@ -52,6 +54,13 @@ export const EmbeddableSwimLaneContainer: FC = ( onLoading, onError, }) => { + useEmbeddableExecutionContext( + services[0].executionContext, + embeddableInput, + ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, + id + ); + const [chartWidth, setChartWidth] = useState(0); const [fromPage, setFromPage] = useState(1); diff --git a/x-pack/plugins/ml/public/embeddables/common/use_embeddable_execution_context.ts b/x-pack/plugins/ml/public/embeddables/common/use_embeddable_execution_context.ts new file mode 100644 index 0000000000000..68306c54c8590 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/common/use_embeddable_execution_context.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import useObservable from 'react-use/lib/useObservable'; +import { map } from 'rxjs/operators'; +import { KibanaExecutionContext } from '@kbn/core/types'; +import { useMemo } from 'react'; +import { useExecutionContext } from '@kbn/kibana-react-plugin/public'; +import type { Observable } from 'rxjs'; +import type { EmbeddableInput } from '@kbn/embeddable-plugin/common'; +import { ExecutionContextStart } from '@kbn/core/public'; + +/** + * Use execution context for ML embeddables. + * @param executionContext + * @param embeddableInput$ + * @param embeddableType + * @param id + */ +export function useEmbeddableExecutionContext( + executionContext: ExecutionContextStart, + embeddableInput$: Observable, + embeddableType: string, + id: string +) { + const parentExecutionContext = useObservable( + embeddableInput$.pipe(map((v) => v.executionContext)) + ); + + const embeddableExecutionContext: KibanaExecutionContext = useMemo(() => { + const child: KibanaExecutionContext = { + type: 'visualization', + name: embeddableType, + id, + }; + + return { + ...parentExecutionContext, + child, + }; + }, [parentExecutionContext, id]); + + useExecutionContext(executionContext, embeddableExecutionContext); +}