Skip to content

Commit

Permalink
[Fleet] Remove usage of deprecated modules for mounting React (#182064)
Browse files Browse the repository at this point in the history
## Summary

Partially addresses elastic/kibana-team#805

These changes come up from searching in the code and finding where
certain kinds of deprecated AppEx-SharedUX modules are imported.
**Reviewers: Please interact with critical paths through the UI
components touched in this PR, ESPECIALLY in terms of testing dark mode
and i18n.**

This PR focuses on code within the **Fleet** domain.

<img width="1196" alt="image"
src="https://github.com/elastic/kibana/assets/908371/7f8d3707-94f0-4746-8dd5-dd858ce027f9">

Note: this also makes inclusion of `i18n` and `analytics` dependencies
consistent. Analytics is an optional dependency for the SharedUX
modules, which wrap `KibanaErrorBoundaryProvider` and is designed to
capture telemetry about errors that are caught in the error boundary.

### 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
- [ ] 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)
  • Loading branch information
tsullivan authored May 3, 2024
1 parent 72ac741 commit 81cab80
Show file tree
Hide file tree
Showing 18 changed files with 171 additions and 202 deletions.
72 changes: 31 additions & 41 deletions x-pack/plugins/fleet/public/applications/fleet/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

import React, { memo, useEffect, useState } from 'react';
import type { AppMountParameters } from '@kbn/core/public';
import { EuiErrorBoundary, EuiPortal } from '@elastic/eui';
import { EuiPortal } from '@elastic/eui';
import type { History } from 'history';
import { Redirect, useRouteMatch } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import useObservable from 'react-use/lib/useObservable';
Expand All @@ -19,8 +20,6 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

import type { TopNavMenuData } from '@kbn/navigation-plugin/public';

import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';

import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
Expand Down Expand Up @@ -171,7 +170,6 @@ export const FleetAppContext: React.FC<{
history: AppMountParameters['history'];
kibanaVersion: string;
extensions: UIExtensionsStorage;
theme$: AppMountParameters['theme$'];
/** For testing purposes only */
routerHistory?: History<any>;
fleetStatus?: FleetStatusProviderProps;
Expand All @@ -184,49 +182,41 @@ export const FleetAppContext: React.FC<{
history,
kibanaVersion,
extensions,
routerHistory,
theme$,
routerHistory: _routerHistory,
fleetStatus,
}) => {
const darkModeObservable = useObservable(theme$);
const darkModeObservable = useObservable(startServices.theme.theme$);
const isDarkMode = darkModeObservable && darkModeObservable.darkMode;

return (
<RedirectAppLinks
coreStart={{
application: startServices.application,
}}
>
<startServices.i18n.Context>
<KibanaContextProvider services={{ ...startServices, theme: { theme$ } }}>
<EuiErrorBoundary>
<ConfigContext.Provider value={config}>
<KibanaVersionContext.Provider value={kibanaVersion}>
<KibanaThemeProvider theme$={theme$}>
<EuiThemeProvider darkMode={isDarkMode}>
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools initialIsOpen={false} />
<UIExtensionsContext.Provider value={extensions}>
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
<Router history={history}>
<PackageInstallProvider
notifications={startServices.notifications}
theme$={theme$}
>
<FlyoutContextProvider>{children}</FlyoutContextProvider>
</PackageInstallProvider>
</Router>
</FleetStatusProvider>
</UIExtensionsContext.Provider>
</QueryClientProvider>
</EuiThemeProvider>
</KibanaThemeProvider>
</KibanaVersionContext.Provider>
</ConfigContext.Provider>
</EuiErrorBoundary>
<KibanaRenderContextProvider {...startServices}>
<RedirectAppLinks
coreStart={{
application: startServices.application,
}}
>
<KibanaContextProvider services={{ ...startServices }}>
<ConfigContext.Provider value={config}>
<KibanaVersionContext.Provider value={kibanaVersion}>
<EuiThemeProvider darkMode={isDarkMode}>
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools initialIsOpen={false} />
<UIExtensionsContext.Provider value={extensions}>
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
<Router history={history}>
<PackageInstallProvider startServices={startServices}>
<FlyoutContextProvider>{children}</FlyoutContextProvider>
</PackageInstallProvider>
</Router>
</FleetStatusProvider>
</UIExtensionsContext.Provider>
</QueryClientProvider>
</EuiThemeProvider>
</KibanaVersionContext.Provider>
</ConfigContext.Provider>
</KibanaContextProvider>
</startServices.i18n.Context>
</RedirectAppLinks>
</RedirectAppLinks>
</KibanaRenderContextProvider>
);
}
);
Expand Down
6 changes: 1 addition & 5 deletions x-pack/plugins/fleet/public/applications/fleet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ interface FleetAppProps {
kibanaVersion: string;
extensions: UIExtensionsStorage;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
theme$: AppMountParameters['theme$'];
}
const FleetApp = ({
startServices,
Expand All @@ -48,7 +47,6 @@ const FleetApp = ({
kibanaVersion,
extensions,
setHeaderActionMenu,
theme$,
}: FleetAppProps) => {
return (
<FleetAppContext
Expand All @@ -57,7 +55,6 @@ const FleetApp = ({
history={history}
kibanaVersion={kibanaVersion}
extensions={extensions}
theme$={theme$}
>
<WithPermissionsAndSetup>
<AppRoutes setHeaderActionMenu={setHeaderActionMenu} />
Expand All @@ -68,7 +65,7 @@ const FleetApp = ({

export function renderApp(
startServices: FleetStartServices,
{ element, history, setHeaderActionMenu, theme$ }: AppMountParameters,
{ element, history, setHeaderActionMenu }: AppMountParameters,
config: FleetConfigType,
kibanaVersion: string,
extensions: UIExtensionsStorage
Expand All @@ -81,7 +78,6 @@ export function renderApp(
kibanaVersion={kibanaVersion}
extensions={extensions}
setHeaderActionMenu={setHeaderActionMenu}
theme$={theme$}
/>,
element
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ describe('edit package policy page', () => {
render();

await waitFor(() => {
expect(renderResult.getByTestId('euiErrorBoundary')).toBeVisible();
expect(renderResult.getByTestId('errorBoundaryFatalHeader')).toBeVisible();
});
});

Expand Down
88 changes: 40 additions & 48 deletions x-pack/plugins/fleet/public/applications/integrations/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React, { memo } from 'react';
import type { AppMountParameters } from '@kbn/core/public';
import { EuiErrorBoundary, EuiPortal } from '@elastic/eui';
import { EuiPortal } from '@elastic/eui';
import type { History } from 'history';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
Expand All @@ -16,11 +16,10 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';

import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';

import type { FleetConfigType, FleetStartServices } from '../../plugin';

import {
Expand Down Expand Up @@ -59,7 +58,6 @@ export const IntegrationsAppContext: React.FC<{
kibanaVersion: string;
extensions: UIExtensionsStorage;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
theme$: AppMountParameters['theme$'];
/** For testing purposes only */
routerHistory?: History<any>; // TODO remove
fleetStatus?: FleetStatusProviderProps;
Expand All @@ -73,59 +71,53 @@ export const IntegrationsAppContext: React.FC<{
kibanaVersion,
extensions,
setHeaderActionMenu,
theme$,
fleetStatus,
}) => {
const theme = useObservable(theme$);
const theme = useObservable(startServices.theme.theme$);
const isDarkMode = theme && theme.darkMode;

const CloudContext = startServices.cloud?.CloudContextProvider || EmptyContext;

return (
<RedirectAppLinks
coreStart={{
application: startServices.application,
}}
>
<startServices.i18n.Context>
<KibanaRenderContextProvider {...startServices}>
<RedirectAppLinks
coreStart={{
application: startServices.application,
}}
>
<KibanaContextProvider services={{ ...startServices }}>
<EuiErrorBoundary>
<ConfigContext.Provider value={config}>
<KibanaVersionContext.Provider value={kibanaVersion}>
<KibanaThemeProvider theme$={theme$}>
<EuiThemeProvider darkMode={isDarkMode}>
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools initialIsOpen={false} />
<UIExtensionsContext.Provider value={extensions}>
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
<startServices.customIntegrations.ContextProvider>
<CloudContext>
<Router history={history}>
<AgentPolicyContextProvider>
<PackageInstallProvider
notifications={startServices.notifications}
theme$={theme$}
>
<FlyoutContextProvider>
<IntegrationsHeader {...{ setHeaderActionMenu, theme$ }} />
{children}
</FlyoutContextProvider>
</PackageInstallProvider>
</AgentPolicyContextProvider>
</Router>
</CloudContext>
</startServices.customIntegrations.ContextProvider>
</FleetStatusProvider>
</UIExtensionsContext.Provider>
</QueryClientProvider>
</EuiThemeProvider>
</KibanaThemeProvider>
</KibanaVersionContext.Provider>
</ConfigContext.Provider>
</EuiErrorBoundary>
<ConfigContext.Provider value={config}>
<KibanaVersionContext.Provider value={kibanaVersion}>
<EuiThemeProvider darkMode={isDarkMode}>
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools initialIsOpen={false} />
<UIExtensionsContext.Provider value={extensions}>
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
<startServices.customIntegrations.ContextProvider>
<CloudContext>
<Router history={history}>
<AgentPolicyContextProvider>
<PackageInstallProvider startServices={startServices}>
<FlyoutContextProvider>
<IntegrationsHeader
{...{ setHeaderActionMenu, startServices }}
/>
{children}
</FlyoutContextProvider>
</PackageInstallProvider>
</AgentPolicyContextProvider>
</Router>
</CloudContext>
</startServices.customIntegrations.ContextProvider>
</FleetStatusProvider>
</UIExtensionsContext.Provider>
</QueryClientProvider>
</EuiThemeProvider>
</KibanaVersionContext.Provider>
</ConfigContext.Provider>
</KibanaContextProvider>
</startServices.i18n.Context>
</RedirectAppLinks>
</RedirectAppLinks>
</KibanaRenderContextProvider>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ import { EuiHeaderSectionItem, EuiHeaderSection, EuiHeaderLinks } from '@elastic

import type { AppMountParameters } from '@kbn/core/public';

import type { FleetStartServices } from '../../../../plugin';

import { HeaderPortal } from './header_portal';
import { DeploymentDetails } from './deployment_details';

export const IntegrationsHeader = ({
setHeaderActionMenu,
theme$,
startServices,
}: {
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
theme$: AppMountParameters['theme$'];
startServices: Pick<FleetStartServices, 'analytics' | 'i18n' | 'theme'>;
}) => {
return (
<HeaderPortal {...{ setHeaderActionMenu, theme$ }}>
<HeaderPortal {...{ setHeaderActionMenu, startServices }}>
<EuiHeaderSection grow={false}>
<EuiHeaderSectionItem>
<EuiHeaderLinks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@ import type { FC } from 'react';
import React, { useEffect, useMemo } from 'react';
import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';

import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';

import type { FleetStartServices } from '../../../../plugin';

export interface Props {
children: React.ReactNode;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
theme$: AppMountParameters['theme$'];
startServices: Pick<FleetStartServices, 'analytics' | 'i18n' | 'theme'>;
}

export const HeaderPortal: FC<Props> = ({ children, setHeaderActionMenu, theme$ }) => {
export const HeaderPortal: FC<Props> = ({ children, setHeaderActionMenu, startServices }) => {
const portalNode = useMemo(() => createHtmlPortalNode(), []);

useEffect(() => {
setHeaderActionMenu((element) => {
const mount = toMountPoint(<OutPortal node={portalNode} />, { theme$ });
const mount = toMountPoint(<OutPortal node={portalNode} />, startServices);
return mount(element);
});

return () => {
portalNode.unmount();
setHeaderActionMenu(undefined);
};
}, [portalNode, setHeaderActionMenu, theme$]);
}, [portalNode, setHeaderActionMenu, startServices]);

return <InPortal node={portalNode}>{children}</InPortal>;
};
Loading

0 comments on commit 81cab80

Please sign in to comment.