diff --git a/src/plugins/kibana_react/public/context/context.tsx b/src/plugins/kibana_react/public/context/context.tsx index fd81bb34e9861..8c32bdab69b31 100644 --- a/src/plugins/kibana_react/public/context/context.tsx +++ b/src/plugins/kibana_react/public/context/context.tsx @@ -7,12 +7,7 @@ */ import * as React from 'react'; -import type { - KibanaEnvironment, - KibanaReactContext, - KibanaReactContextValue, - KibanaServices, -} from './types'; +import { KibanaReactContext, KibanaReactContextValue, KibanaServices } from './types'; import { createReactOverlays } from '../overlays'; import { createNotifications } from '../notifications'; @@ -20,7 +15,6 @@ const { useMemo, useContext, createElement, createContext } = React; const defaultContextValue = { services: {}, - kibanaEnvironment: {}, overlays: createReactOverlays({}), notifications: createNotifications({}), }; @@ -43,29 +37,22 @@ export const withKibana = } }; export const createKibanaReactContext = ( - services: Services, - kibanaEnvironment?: KibanaEnvironment + services: Services ): KibanaReactContext => { const value: KibanaReactContextValue = { services, overlays: createReactOverlays(services), notifications: createNotifications(services), - kibanaEnvironment: kibanaEnvironment ?? {}, }; - const Provider: React.FC<{ services?: Services; kibanaEnvironment?: KibanaEnvironment }> = ({ + const Provider: React.FC<{ services?: Services }> = ({ services: newServices = {}, - kibanaEnvironment: newKibanaEnvironment = {}, children, }) => { const oldValue = useKibana(); const { value: newValue } = useMemo( - () => - createKibanaReactContext( - { ...services, ...oldValue.services, ...newServices }, - { ...kibanaEnvironment, ...oldValue.kibanaEnvironment, ...newKibanaEnvironment } - ), - [services, oldValue, newServices, kibanaEnvironment, newKibanaEnvironment] + () => createKibanaReactContext({ ...services, ...oldValue.services, ...newServices }), + [services, oldValue, newServices] ); const newProvider = createElement(context.Provider, { @@ -83,4 +70,4 @@ export const createKibanaReactContext = ( }; }; -export const { Provider: KibanaContextProvider } = createKibanaReactContext({}, {}); +export const { Provider: KibanaContextProvider } = createKibanaReactContext({}); diff --git a/src/plugins/kibana_react/public/context/types.ts b/src/plugins/kibana_react/public/context/types.ts index 7307611defe59..4962267974d79 100644 --- a/src/plugins/kibana_react/public/context/types.ts +++ b/src/plugins/kibana_react/public/context/types.ts @@ -12,21 +12,15 @@ import { KibanaReactOverlays } from '../overlays'; import { KibanaReactNotifications } from '../notifications'; export type KibanaServices = Partial; -export interface KibanaEnvironment { - kibanaVersion?: string; - isCloudEnv?: boolean; - isServerlessEnv?: boolean; -} export interface KibanaReactContextValue { readonly services: Services; - readonly kibanaEnvironment: KibanaEnvironment; readonly overlays: KibanaReactOverlays; readonly notifications: KibanaReactNotifications; } export interface KibanaReactContext { value: KibanaReactContextValue; - Provider: React.FC<{ services?: T; kibanaEnvironment?: KibanaEnvironment }>; + Provider: React.FC<{ services?: T }>; Consumer: React.Consumer>; } diff --git a/x-pack/plugins/apm/public/components/routing/app_root/index.tsx b/x-pack/plugins/apm/public/components/routing/app_root/index.tsx index 0a18ebb584898..d540730dfbca0 100644 --- a/x-pack/plugins/apm/public/components/routing/app_root/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/app_root/index.tsx @@ -21,6 +21,7 @@ import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config'; import { euiDarkVars, euiLightVars } from '@kbn/ui-theme'; import React from 'react'; import { DefaultTheme, ThemeProvider } from 'styled-components'; +import { useKibanaEnvironmentContextProvider } from '../../../context/kibana_environment_context/use_kibana_environment_context'; import { AnomalyDetectionJobsContextProvider } from '../../../context/anomaly_detection_jobs/anomaly_detection_jobs_context'; import { ApmPluginContext, @@ -55,6 +56,8 @@ export function ApmAppRoot({ apmServices: ApmServices; }) { const { appMountParameters, core } = apmPluginContextValue; + const KibanaEnvironmentContextProvider = + useKibanaEnvironmentContextProvider(pluginsStart); const { history } = appMountParameters; const i18nCore = core.i18n; @@ -72,52 +75,49 @@ export function ApmAppRoot({ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx index a9ad169aa23a6..5e2e0964be791 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx @@ -9,9 +9,10 @@ import { EuiFlexGroup, EuiFlexItem, EuiPageHeaderProps } from '@elastic/eui'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { ObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; -import React from 'react'; +import React, { useContext } from 'react'; import { useLocation } from 'react-router-dom'; import { FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; +import { KibanaEnvironmentContext } from '../../../context/kibana_environment_context/kibana_environment_context'; import { getPathForFeedback } from '../../../utils/get_path_for_feedback'; import { EnvironmentsContextProvider } from '../../../context/environments_context/environments_context'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; @@ -58,7 +59,8 @@ export function ApmMainTemplate({ Pick) { const location = useLocation(); - const { services, kibanaEnvironment } = useKibana(); + const { services } = useKibana(); + const kibanaEnvironment = useContext(KibanaEnvironmentContext); const { http, docLinks, observabilityShared, application } = services; const { kibanaVersion, isCloudEnv, isServerlessEnv } = kibanaEnvironment; const basePath = http?.basePath.get(); diff --git a/x-pack/plugins/apm/public/context/kibana_environment_context/kibana_environment_context.tsx b/x-pack/plugins/apm/public/context/kibana_environment_context/kibana_environment_context.tsx new file mode 100644 index 0000000000000..acf974d4d2dae --- /dev/null +++ b/x-pack/plugins/apm/public/context/kibana_environment_context/kibana_environment_context.tsx @@ -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 { createContext } from 'react'; + +export interface KibanaEnvContext { + kibanaVersion?: string; + isCloudEnv?: boolean; + isServerlessEnv?: boolean; +} + +export const KibanaEnvironmentContext = createContext({}); diff --git a/x-pack/plugins/apm/public/context/kibana_environment_context/use_kibana_environment_context.tsx b/x-pack/plugins/apm/public/context/kibana_environment_context/use_kibana_environment_context.tsx new file mode 100644 index 0000000000000..01a4b22bc0890 --- /dev/null +++ b/x-pack/plugins/apm/public/context/kibana_environment_context/use_kibana_environment_context.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo, createElement } from 'react'; +import { ApmPluginStartDeps } from '../../plugin'; +import { + KibanaEnvironmentContext, + type KibanaEnvContext, +} from './kibana_environment_context'; + +export const useKibanaEnvironmentContextProvider = ( + plugins: ApmPluginStartDeps +) => { + const value = useMemo( + () => ({ + kibanaVersion: plugins.kibanaVersion, + isCloudEnv: plugins.isCloudEnv, + isServerlessEnv: plugins.isServerlessEnv, + }), + [plugins] + ); + + const Provider: React.FC<{ kibanaEnvironment?: KibanaEnvContext }> = ({ + kibanaEnvironment = {}, + children, + }) => { + const newProvider = createElement(KibanaEnvironmentContext.Provider, { + value: { ...kibanaEnvironment, ...value }, + children, + }); + + return newProvider; + }; + + return Provider; +}; diff --git a/x-pack/plugins/infra/public/apps/common_providers.tsx b/x-pack/plugins/infra/public/apps/common_providers.tsx index 158e0b95293e9..9ee0053c79e6a 100644 --- a/x-pack/plugins/infra/public/apps/common_providers.tsx +++ b/x-pack/plugins/infra/public/apps/common_providers.tsx @@ -13,7 +13,10 @@ import type { ObservabilityAIAssistantPluginStart } from '@kbn/observability-ai- import { Storage } from '@kbn/kibana-utils-plugin/public'; import { NavigationWarningPromptProvider } from '@kbn/observability-shared-plugin/public'; import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; -import { useKibanaContextForPluginProvider } from '../hooks/use_kibana'; +import { + useKibanaContextForPluginProvider, + useKibanaEnvironmentContextProvider, +} from '../hooks/use_kibana'; import { InfraClientStartDeps, InfraClientStartExports } from '../types'; import { HeaderActionMenuProvider } from '../utils/header_action_menu_provider'; import { TriggersActionsProvider } from '../utils/triggers_actions_context'; @@ -70,11 +73,15 @@ export const CoreProviders: React.FC = ({ pluginStart ); + const MyEnvContextForPluginProvider = useKibanaEnvironmentContextProvider(plugins); + return ( - - {children} - + + + {children} + + ); }; diff --git a/x-pack/plugins/infra/public/hooks/use_kibana.tsx b/x-pack/plugins/infra/public/hooks/use_kibana.tsx index f1b83f6a229f5..f8e9c7dab48fd 100644 --- a/x-pack/plugins/infra/public/hooks/use_kibana.tsx +++ b/x-pack/plugins/infra/public/hooks/use_kibana.tsx @@ -6,7 +6,7 @@ */ import type { PropsOf } from '@elastic/eui'; -import React, { useMemo } from 'react'; +import React, { useMemo, createElement, createContext } from 'react'; import { CoreStart } from '@kbn/core/public'; import { createKibanaReactContext, @@ -17,23 +17,24 @@ import { InfraClientCoreSetup, InfraClientStartDeps, InfraClientStartExports } f export type PluginKibanaContextValue = CoreStart & InfraClientStartDeps & InfraClientStartExports; +interface KibanaEnvContext { + kibanaVersion?: string; + isCloudEnv?: boolean; + isServerlessEnv?: boolean; +} + export const createKibanaContextForPlugin = ( core: CoreStart, plugins: InfraClientStartDeps, pluginStart: InfraClientStartExports ) => - createKibanaReactContext( - { - ...core, - ...plugins, - ...pluginStart, - }, - { - kibanaVersion: plugins.kibanaVersion, - isCloudEnv: plugins.isCloudEnv, - isServerlessEnv: plugins.isServerlessEnv, - } - ); + createKibanaReactContext({ + ...core, + ...plugins, + ...pluginStart, + }); + +export const KibanaEnvironmentContext = createContext({}); export const useKibanaContextForPlugin = useKibana as () => KibanaReactContextValue; @@ -50,6 +51,31 @@ export const useKibanaContextForPluginProvider = ( return Provider; }; +export const useKibanaEnvironmentContextProvider = (plugins: InfraClientStartDeps) => { + const value = useMemo( + () => ({ + kibanaVersion: plugins.kibanaVersion, + isCloudEnv: plugins.isCloudEnv, + isServerlessEnv: plugins.isServerlessEnv, + }), + [plugins] + ); + + const Provider: React.FC<{ kibanaEnvironment?: KibanaEnvContext }> = ({ + kibanaEnvironment = {}, + children, + }) => { + const newProvider = createElement(KibanaEnvironmentContext.Provider, { + value: { ...kibanaEnvironment, ...value }, + children, + }); + + return newProvider; + }; + + return Provider; +}; + export const createLazyComponentWithKibanaContext = >( coreSetup: InfraClientCoreSetup, lazyComponentFactory: () => Promise<{ default: T }> diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx index 726f501c6be71..8766a8bdddf2e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx @@ -6,12 +6,12 @@ */ import { EuiErrorBoundary } from '@elastic/eui'; -import React from 'react'; +import React, { useContext } from 'react'; import { useTrackPageview, FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; import { APP_WRAPPER_CLASS } from '@kbn/core/public'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; -import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; +import { KibanaEnvironmentContext } from '../../../hooks/use_kibana'; import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { useSourceContext } from '../../../containers/metrics_source'; @@ -29,9 +29,7 @@ const HOSTS_FEEDBACK_LINK = export const HostsPage = () => { const { isLoading, loadSourceFailureMessage, loadSource, source } = useSourceContext(); - const { - kibanaEnvironment: { kibanaVersion, isCloudEnv, isServerlessEnv }, - } = useKibanaContextForPlugin(); + const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext); useTrackPageview({ app: 'infra_metrics', path: 'hosts' }); useTrackPageview({ app: 'infra_metrics', path: 'hosts', delay: 15000 }); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx index 3f0448942f738..c5524bae4eb41 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx @@ -6,11 +6,11 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiGlobalToastList } from '@elastic/eui'; -import React from 'react'; +import React, { useContext } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import { FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; -import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; +import { KibanaEnvironmentContext } from '../../../../hooks/use_kibana'; const KUBERNETES_TOAST_STORAGE_KEY = 'kubernetesToastKey'; const KUBERNETES_FEEDBACK_LINK = 'https://ela.st/k8s-feedback'; @@ -18,9 +18,8 @@ const KUBERNETES_FEEDBACK_LINK = 'https://ela.st/k8s-feedback'; export const SurveyKubernetes = () => { const [isToastSeen, setIsToastSeen] = useLocalStorage(KUBERNETES_TOAST_STORAGE_KEY, false); const markToastAsSeen = () => setIsToastSeen(true); - const { - kibanaEnvironment: { kibanaVersion, isCloudEnv, isServerlessEnv }, - } = useKibanaContextForPlugin(); + + const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext); return ( <> diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_section.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_section.tsx index 840522efa1722..d32fd722c8391 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_section.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_section.tsx @@ -5,9 +5,9 @@ * 2.0. */ -import React from 'react'; +import React, { useContext } from 'react'; import { FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; -import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; +import { KibanaEnvironmentContext } from '../../../../hooks/use_kibana'; import { useWaffleOptionsContext } from '../hooks/use_waffle_options'; import { SurveyKubernetes } from './survey_kubernetes'; @@ -16,9 +16,7 @@ const INVENTORY_FEEDBACK_LINK = 'https://ela.st/survey-infra-inventory?usp=pp_ur export const SurveySection = () => { const { nodeType } = useWaffleOptionsContext(); - const { - kibanaEnvironment: { kibanaVersion, isCloudEnv, isServerlessEnv }, - } = useKibanaContextForPlugin(); + const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext); return ( <> diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx index 061768e2a8042..d7764c14c4364 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx @@ -7,9 +7,9 @@ import { EuiErrorBoundary } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { useTrackPageview, FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; -import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; +import { KibanaEnvironmentContext } from '../../../hooks/use_kibana'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { useMetricsExplorerViews } from '../../../hooks/use_metrics_explorer_views'; import { MetricsSourceConfigurationProperties } from '../../../../common/metrics_sources'; @@ -52,9 +52,7 @@ export const MetricsExplorerPage = ({ source, derivedIndexPattern }: MetricsExpl } = useMetricsExplorerState(source, derivedIndexPattern, enabled); const { currentView } = useMetricsExplorerViews(); const { source: sourceContext, metricIndicesExist } = useSourceContext(); - const { - kibanaEnvironment: { kibanaVersion, isCloudEnv, isServerlessEnv }, - } = useKibanaContextForPlugin(); + const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext); useTrackPageview({ app: 'infra_metrics', path: 'metrics_explorer' }); useTrackPageview({ app: 'infra_metrics', path: 'metrics_explorer', delay: 15000 });