mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Fleet] Remove usage of deprecated modules for mounting React (#182064)
## Summary
Partially addresses https://github.com/elastic/kibana-team/issues/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="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)
This commit is contained in:
parent
72ac7413c9
commit
81cab806c8
18 changed files with 171 additions and 202 deletions
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -39,7 +39,6 @@ interface FleetAppProps {
|
|||
kibanaVersion: string;
|
||||
extensions: UIExtensionsStorage;
|
||||
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
|
||||
theme$: AppMountParameters['theme$'];
|
||||
}
|
||||
const FleetApp = ({
|
||||
startServices,
|
||||
|
@ -48,7 +47,6 @@ const FleetApp = ({
|
|||
kibanaVersion,
|
||||
extensions,
|
||||
setHeaderActionMenu,
|
||||
theme$,
|
||||
}: FleetAppProps) => {
|
||||
return (
|
||||
<FleetAppContext
|
||||
|
@ -57,7 +55,6 @@ const FleetApp = ({
|
|||
history={history}
|
||||
kibanaVersion={kibanaVersion}
|
||||
extensions={extensions}
|
||||
theme$={theme$}
|
||||
>
|
||||
<WithPermissionsAndSetup>
|
||||
<AppRoutes setHeaderActionMenu={setHeaderActionMenu} />
|
||||
|
@ -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
|
||||
|
@ -81,7 +78,6 @@ export function renderApp(
|
|||
kibanaVersion={kibanaVersion}
|
||||
extensions={extensions}
|
||||
setHeaderActionMenu={setHeaderActionMenu}
|
||||
theme$={theme$}
|
||||
/>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -355,7 +355,7 @@ describe('edit package policy page', () => {
|
|||
render();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(renderResult.getByTestId('euiErrorBoundary')).toBeVisible();
|
||||
expect(renderResult.getByTestId('errorBoundaryFatalHeader')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,20 +10,22 @@ 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);
|
||||
});
|
||||
|
||||
|
@ -31,7 +33,7 @@ export const HeaderPortal: FC<Props> = ({ children, setHeaderActionMenu, theme$
|
|||
portalNode.unmount();
|
||||
setHeaderActionMenu(undefined);
|
||||
};
|
||||
}, [portalNode, setHeaderActionMenu, theme$]);
|
||||
}, [portalNode, setHeaderActionMenu, startServices]);
|
||||
|
||||
return <InPortal node={portalNode}>{children}</InPortal>;
|
||||
};
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { DocLinksStart, OverlayStart } from '@kbn/core/public';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
|
@ -15,15 +15,13 @@ import { ConfirmForceInstallModal } from '../components';
|
|||
|
||||
const confirmForceInstall = ({
|
||||
pkg,
|
||||
overlays,
|
||||
docLinks,
|
||||
core,
|
||||
}: {
|
||||
pkg: { name: string; version: string };
|
||||
overlays: OverlayStart;
|
||||
docLinks: DocLinksStart;
|
||||
core: CoreStart;
|
||||
}): Promise<boolean> =>
|
||||
new Promise((resolve) => {
|
||||
const session = overlays.openModal(
|
||||
const session = core.overlays.openModal(
|
||||
toMountPoint(
|
||||
<ConfirmForceInstallModal
|
||||
pkg={pkg}
|
||||
|
@ -35,17 +33,18 @@ const confirmForceInstall = ({
|
|||
session.close();
|
||||
resolve(false);
|
||||
}}
|
||||
docLinks={docLinks}
|
||||
/>
|
||||
docLinks={core.docLinks}
|
||||
/>,
|
||||
core
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
export const useConfirmForceInstall = () => {
|
||||
const { overlays, docLinks } = useStartServices();
|
||||
const core = useStartServices();
|
||||
|
||||
return useCallback(
|
||||
(pkg: { name: string; version: string }) => confirmForceInstall({ pkg, overlays, docLinks }),
|
||||
[docLinks, overlays]
|
||||
(pkg: { name: string; version: string }) => confirmForceInstall({ pkg, core }),
|
||||
[core]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,26 +5,31 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { DocLinksStart, OverlayStart } from '@kbn/core/public';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
// Direct imports are important here, importing all hooks breaks unit tests
|
||||
// and increases bundle size because this is imported on first page load
|
||||
import type { FleetStartServices } from '../../../plugin';
|
||||
|
||||
import { useStartServices } from '../../../hooks/use_core';
|
||||
import { ConfirmOpenUnverifiedModal } from '../components/confirm_open_unverified_modal';
|
||||
|
||||
type StartServicesConfirmOpen = Pick<
|
||||
FleetStartServices,
|
||||
'docLinks' | 'overlays' | 'analytics' | 'i18n' | 'theme'
|
||||
>;
|
||||
|
||||
const confirmOpenUnverified = ({
|
||||
pkgName,
|
||||
overlays,
|
||||
docLinks,
|
||||
fleetServices,
|
||||
}: {
|
||||
pkgName: string;
|
||||
overlays: OverlayStart;
|
||||
docLinks: DocLinksStart;
|
||||
fleetServices: StartServicesConfirmOpen;
|
||||
}): Promise<boolean> =>
|
||||
new Promise((resolve) => {
|
||||
const { overlays, docLinks, ...startServices } = fleetServices;
|
||||
const session = overlays.openModal(
|
||||
toMountPoint(
|
||||
<ConfirmOpenUnverifiedModal
|
||||
|
@ -38,16 +43,17 @@ const confirmOpenUnverified = ({
|
|||
resolve(false);
|
||||
}}
|
||||
docLinks={docLinks}
|
||||
/>
|
||||
/>,
|
||||
startServices
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
export const useConfirmOpenUnverified = () => {
|
||||
const { overlays, docLinks } = useStartServices();
|
||||
const fleetServices = useStartServices();
|
||||
|
||||
return useCallback(
|
||||
(pkgName: string) => confirmOpenUnverified({ pkgName, overlays, docLinks }),
|
||||
[docLinks, overlays]
|
||||
(pkgName: string) => confirmOpenUnverified({ pkgName, fleetServices }),
|
||||
[fleetServices]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,14 +7,22 @@
|
|||
|
||||
import React from 'react';
|
||||
import { act, type WrapperComponent } from '@testing-library/react-hooks';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
|
||||
import { createIntegrationsTestRendererMock } from '../../../mock';
|
||||
|
||||
import { useInstallPackage, PackageInstallProvider } from './use_package_install';
|
||||
|
||||
describe('usePackageInstall', () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
|
||||
const addErrorSpy = jest.spyOn(coreStart.notifications.toasts, 'addError');
|
||||
const addSuccessSpy = jest.spyOn(coreStart.notifications.toasts, 'addSuccess');
|
||||
|
||||
beforeEach(() => {
|
||||
createIntegrationsTestRendererMock();
|
||||
addErrorSpy.mockReset();
|
||||
addSuccessSpy.mockReset();
|
||||
});
|
||||
|
||||
describe('useInstallPackage', () => {
|
||||
|
@ -40,14 +48,8 @@ describe('usePackageInstall', () => {
|
|||
throw error;
|
||||
}) as any);
|
||||
|
||||
const notifications = renderer.startServices.notifications;
|
||||
const wrapper: WrapperComponent<any> = ({ children }) => (
|
||||
<PackageInstallProvider
|
||||
notifications={notifications}
|
||||
theme$={renderer.startServices.theme.theme$}
|
||||
>
|
||||
{children}
|
||||
</PackageInstallProvider>
|
||||
<PackageInstallProvider startServices={coreStart}>{children}</PackageInstallProvider>
|
||||
);
|
||||
const { result } = renderer.renderHook(() => useInstallPackage(), wrapper);
|
||||
|
||||
|
@ -55,12 +57,11 @@ describe('usePackageInstall', () => {
|
|||
|
||||
return {
|
||||
installPackage,
|
||||
notifications,
|
||||
};
|
||||
}
|
||||
|
||||
it('should work for install', async () => {
|
||||
const { notifications, installPackage } = createRenderer();
|
||||
const { installPackage } = createRenderer();
|
||||
let res: boolean | undefined;
|
||||
await act(async () => {
|
||||
res = await installPackage({
|
||||
|
@ -70,14 +71,14 @@ describe('usePackageInstall', () => {
|
|||
});
|
||||
});
|
||||
|
||||
expect(notifications.toasts.addError).not.toBeCalled();
|
||||
expect(notifications.toasts.addSuccess).toBeCalled();
|
||||
expect(addErrorSpy).not.toBeCalled();
|
||||
expect(addSuccessSpy).toBeCalled();
|
||||
|
||||
expect(res).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work for upgrade', async () => {
|
||||
const { notifications, installPackage } = createRenderer();
|
||||
const { installPackage } = createRenderer();
|
||||
let res: boolean | undefined;
|
||||
await act(async () => {
|
||||
res = await installPackage({
|
||||
|
@ -88,14 +89,14 @@ describe('usePackageInstall', () => {
|
|||
});
|
||||
});
|
||||
|
||||
expect(notifications.toasts.addError).not.toBeCalled();
|
||||
expect(notifications.toasts.addSuccess).toBeCalled();
|
||||
expect(addErrorSpy).not.toBeCalled();
|
||||
expect(addSuccessSpy).toBeCalled();
|
||||
|
||||
expect(res).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should handle install error', async () => {
|
||||
const { notifications, installPackage } = createRenderer();
|
||||
const { installPackage } = createRenderer();
|
||||
|
||||
let res: boolean | undefined;
|
||||
await act(async () => {
|
||||
|
@ -106,8 +107,8 @@ describe('usePackageInstall', () => {
|
|||
});
|
||||
});
|
||||
|
||||
expect(notifications.toasts.addSuccess).not.toBeCalled();
|
||||
expect(notifications.toasts.addError).toBeCalled();
|
||||
expect(addSuccessSpy).not.toBeCalled();
|
||||
expect(addErrorSpy).toBeCalled();
|
||||
|
||||
expect(res).toBeFalsy();
|
||||
});
|
||||
|
|
|
@ -13,13 +13,10 @@ import React, { useCallback, useState } from 'react';
|
|||
import { useHistory } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { NotificationsStart } from '@kbn/core/public';
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { CoreTheme } from '@kbn/core/public';
|
||||
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
|
||||
import type { PackageInfo } from '../../../types';
|
||||
import type { FleetStartServices } from '../../../plugin';
|
||||
import { sendInstallPackage, sendRemovePackage, useLink } from '../../../hooks';
|
||||
|
||||
import { InstallStatus } from '../../../types';
|
||||
|
@ -27,6 +24,8 @@ import { isVerificationError } from '../services';
|
|||
|
||||
import { useConfirmForceInstall } from '.';
|
||||
|
||||
type StartServices = Pick<FleetStartServices, 'notifications' | 'analytics' | 'i18n' | 'theme'>;
|
||||
|
||||
interface PackagesInstall {
|
||||
[key: string]: PackageInstallItem;
|
||||
}
|
||||
|
@ -43,13 +42,7 @@ type InstallPackageProps = Pick<PackageInfo, 'name' | 'version' | 'title'> & {
|
|||
};
|
||||
type SetPackageInstallStatusProps = Pick<PackageInfo, 'name'> & PackageInstallItem;
|
||||
|
||||
function usePackageInstall({
|
||||
notifications,
|
||||
theme$,
|
||||
}: {
|
||||
notifications: NotificationsStart;
|
||||
theme$: Observable<CoreTheme>;
|
||||
}) {
|
||||
function usePackageInstall({ startServices }: { startServices: StartServices }) {
|
||||
const history = useHistory();
|
||||
const { getPath } = useLink();
|
||||
const [packages, setPackage] = useState<PackagesInstall>({});
|
||||
|
@ -68,6 +61,8 @@ function usePackageInstall({
|
|||
[]
|
||||
);
|
||||
|
||||
const { notifications } = startServices;
|
||||
|
||||
const getPackageInstallStatus = useCallback(
|
||||
(pkg: string): PackageInstallItem => {
|
||||
return packages[pkg];
|
||||
|
@ -115,7 +110,7 @@ function usePackageInstall({
|
|||
defaultMessage="Reinstalled {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
|
@ -123,7 +118,7 @@ function usePackageInstall({
|
|||
defaultMessage="Successfully reinstalled {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
});
|
||||
} else if (isUpgrade) {
|
||||
|
@ -134,7 +129,7 @@ function usePackageInstall({
|
|||
defaultMessage="Upgraded {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
|
@ -142,7 +137,7 @@ function usePackageInstall({
|
|||
defaultMessage="Successfully upgraded {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
});
|
||||
} else {
|
||||
|
@ -153,7 +148,7 @@ function usePackageInstall({
|
|||
defaultMessage="Installed {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
|
@ -161,7 +156,7 @@ function usePackageInstall({
|
|||
defaultMessage="Successfully installed {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -192,14 +187,7 @@ function usePackageInstall({
|
|||
return true;
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[
|
||||
getPackageInstallStatus,
|
||||
setPackageInstallStatus,
|
||||
notifications.toasts,
|
||||
theme$,
|
||||
getPath,
|
||||
history,
|
||||
]
|
||||
[getPackageInstallStatus, setPackageInstallStatus, startServices, getPath, history]
|
||||
);
|
||||
|
||||
const uninstallPackage = useCallback(
|
||||
|
@ -221,14 +209,14 @@ function usePackageInstall({
|
|||
defaultMessage="Failed to uninstall {title} package"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.integrations.packageUninstallErrorDescription"
|
||||
defaultMessage="Something went wrong while trying to uninstall this package. Please try again later."
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
iconType: 'error',
|
||||
});
|
||||
|
@ -242,7 +230,7 @@ function usePackageInstall({
|
|||
defaultMessage="Uninstalled {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
|
@ -250,7 +238,7 @@ function usePackageInstall({
|
|||
defaultMessage="Successfully uninstalled {title}"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
});
|
||||
if (redirectToVersion !== version) {
|
||||
|
@ -261,7 +249,7 @@ function usePackageInstall({
|
|||
}
|
||||
}
|
||||
},
|
||||
[notifications.toasts, setPackageInstallStatus, getPath, history, theme$]
|
||||
[notifications.toasts, setPackageInstallStatus, getPath, history, startServices]
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
|
@ -40,7 +40,6 @@ interface IntegrationsAppProps {
|
|||
kibanaVersion: string;
|
||||
extensions: UIExtensionsStorage;
|
||||
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
|
||||
theme$: AppMountParameters['theme$'];
|
||||
}
|
||||
const IntegrationsApp = ({
|
||||
basepath,
|
||||
|
@ -50,7 +49,6 @@ const IntegrationsApp = ({
|
|||
kibanaVersion,
|
||||
extensions,
|
||||
setHeaderActionMenu,
|
||||
theme$,
|
||||
}: IntegrationsAppProps) => {
|
||||
return (
|
||||
<IntegrationsAppContext
|
||||
|
@ -61,7 +59,6 @@ const IntegrationsApp = ({
|
|||
kibanaVersion={kibanaVersion}
|
||||
extensions={extensions}
|
||||
setHeaderActionMenu={setHeaderActionMenu}
|
||||
theme$={theme$}
|
||||
>
|
||||
<AppRoutes />
|
||||
</IntegrationsAppContext>
|
||||
|
@ -70,7 +67,7 @@ const IntegrationsApp = ({
|
|||
|
||||
export function renderApp(
|
||||
startServices: FleetStartServices,
|
||||
{ element, appBasePath, history, setHeaderActionMenu, theme$ }: AppMountParameters,
|
||||
{ element, appBasePath, history, setHeaderActionMenu }: AppMountParameters,
|
||||
config: FleetConfigType,
|
||||
kibanaVersion: string,
|
||||
extensions: UIExtensionsStorage,
|
||||
|
@ -86,7 +83,6 @@ export function renderApp(
|
|||
kibanaVersion={kibanaVersion}
|
||||
extensions={extensions}
|
||||
setHeaderActionMenu={setHeaderActionMenu}
|
||||
theme$={theme$}
|
||||
/>
|
||||
</UsageTracker>,
|
||||
element
|
||||
|
|
|
@ -783,7 +783,7 @@ export function Detail() {
|
|||
/>
|
||||
</Route>
|
||||
<Route path={INTEGRATIONS_ROUTING_PATHS.integration_details_settings}>
|
||||
<SettingsPage packageInfo={packageInfo} theme$={services.theme.theme$} />
|
||||
<SettingsPage packageInfo={packageInfo} startServices={services} />
|
||||
</Route>
|
||||
<Route path={INTEGRATIONS_ROUTING_PATHS.integration_details_assets}>
|
||||
<AssetsPage packageInfo={packageInfo} refetchPackageInfo={refetchPackageInfo} />
|
||||
|
|
|
@ -23,14 +23,12 @@ import {
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { CoreTheme } from '@kbn/core/public';
|
||||
|
||||
import {
|
||||
getNumTransformAssets,
|
||||
TransformInstallWithCurrentUserPermissionCallout,
|
||||
} from '../../../../../../../components/transform_install_as_current_user_callout';
|
||||
|
||||
import type { FleetStartServices } from '../../../../../../../plugin';
|
||||
import type { PackageInfo } from '../../../../../types';
|
||||
import { InstallStatus } from '../../../../../types';
|
||||
import {
|
||||
|
@ -117,10 +115,10 @@ const LatestVersionLink = ({ name, version }: { name: string; version: string })
|
|||
|
||||
interface Props {
|
||||
packageInfo: PackageInfo;
|
||||
theme$: Observable<CoreTheme>;
|
||||
startServices: Pick<FleetStartServices, 'analytics' | 'i18n' | 'theme'>;
|
||||
}
|
||||
|
||||
export const SettingsPage: React.FC<Props> = memo(({ packageInfo, theme$ }: Props) => {
|
||||
export const SettingsPage: React.FC<Props> = memo(({ packageInfo, startServices }: Props) => {
|
||||
const { name, title, latestVersion, version, keepPoliciesUpToDate } = packageInfo;
|
||||
const [isUpgradingPackagePolicies, setIsUpgradingPackagePolicies] = useState<boolean>(false);
|
||||
const [isChangelogModalOpen, setIsChangelogModalOpen] = useState(false);
|
||||
|
@ -339,7 +337,7 @@ export const SettingsPage: React.FC<Props> = memo(({ packageInfo, theme$ }: Prop
|
|||
dryRunData={dryRunData}
|
||||
isUpgradingPackagePolicies={isUpgradingPackagePolicies}
|
||||
setIsUpgradingPackagePolicies={setIsUpgradingPackagePolicies}
|
||||
theme$={theme$}
|
||||
startServices={startServices}
|
||||
/>
|
||||
</p>
|
||||
</>
|
||||
|
|
|
@ -18,11 +18,10 @@ import {
|
|||
EuiConfirmModal,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { CoreTheme } from '@kbn/core/public';
|
||||
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
|
||||
import type { FleetStartServices } from '../../../../../../../plugin';
|
||||
import type {
|
||||
PackageInfo,
|
||||
UpgradePackagePolicyDryRunResponse,
|
||||
|
@ -45,7 +44,7 @@ interface UpdateButtonProps extends Pick<PackageInfo, 'name' | 'title' | 'versio
|
|||
agentPolicyIds: string[];
|
||||
isUpgradingPackagePolicies?: boolean;
|
||||
setIsUpgradingPackagePolicies?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
theme$: Observable<CoreTheme>;
|
||||
startServices: Pick<FleetStartServices, 'analytics' | 'i18n' | 'theme'>;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -77,7 +76,7 @@ export const UpdateButton: React.FunctionComponent<UpdateButtonProps> = ({
|
|||
setIsUpgradingPackagePolicies = () => {},
|
||||
title,
|
||||
version,
|
||||
theme$,
|
||||
startServices,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
const { getPath } = useLink();
|
||||
|
@ -185,7 +184,7 @@ export const UpdateButton: React.FunctionComponent<UpdateButtonProps> = ({
|
|||
defaultMessage="Updated {title} and upgraded policies"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
text: toMountPoint(
|
||||
<FormattedMessage
|
||||
|
@ -193,7 +192,7 @@ export const UpdateButton: React.FunctionComponent<UpdateButtonProps> = ({
|
|||
defaultMessage="Successfully updated {title} and upgraded policies"
|
||||
values={{ title }}
|
||||
/>,
|
||||
{ theme$ }
|
||||
startServices
|
||||
),
|
||||
});
|
||||
|
||||
|
@ -230,7 +229,7 @@ export const UpdateButton: React.FunctionComponent<UpdateButtonProps> = ({
|
|||
packagePolicyIds,
|
||||
dryRunData,
|
||||
notifications.toasts,
|
||||
theme$,
|
||||
startServices,
|
||||
navigateToNewSettingsPage,
|
||||
]);
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ import type { EuiButtonEmptyProps } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { ViewApiRequestFlyout } from '@kbn/es-ui-shared-plugin/public';
|
||||
import { KibanaContextProvider, toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
|
||||
import { useStartServices } from '../../hooks';
|
||||
|
||||
|
@ -41,7 +42,7 @@ export const DevtoolsRequestFlyoutButton: React.FunctionComponent<
|
|||
description={description}
|
||||
/>
|
||||
</KibanaContextProvider>,
|
||||
{ theme$: services.theme.theme$ }
|
||||
services
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@ import type { RenderHookResult } from '@testing-library/react-hooks';
|
|||
import { Router } from '@kbn/shared-ux-router';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
import { themeServiceMock } from '@kbn/core/public/mocks';
|
||||
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import type { ScopedHistory } from '@kbn/core/public';
|
||||
import { CoreScopedHistory } from '@kbn/core/public';
|
||||
|
@ -103,7 +101,6 @@ export const createFleetTestRendererMock = (): TestRenderer => {
|
|||
kibanaVersion={testRendererMocks.kibanaVersion}
|
||||
extensions={extensions}
|
||||
routerHistory={testRendererMocks.history}
|
||||
theme$={themeServiceMock.createTheme$()}
|
||||
fleetStatus={{
|
||||
enabled: true,
|
||||
isLoading: false,
|
||||
|
@ -167,7 +164,6 @@ export const createIntegrationsTestRendererMock = (): TestRenderer => {
|
|||
kibanaVersion={testRendererMocks.kibanaVersion}
|
||||
extensions={extensions}
|
||||
routerHistory={testRendererMocks.history}
|
||||
theme$={themeServiceMock.createTheme$()}
|
||||
setHeaderActionMenu={() => {}}
|
||||
fleetStatus={{
|
||||
enabled: true,
|
||||
|
|
|
@ -51,6 +51,8 @@ import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/
|
|||
|
||||
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import type { FleetAuthz } from '../common';
|
||||
import { appRoutesService, INTEGRATIONS_PLUGIN_ID, PLUGIN_ID, setupRouteService } from '../common';
|
||||
import {
|
||||
|
@ -85,7 +87,6 @@ import type {
|
|||
import { LazyCustomLogsAssetsExtension } from './lazy_custom_logs_assets_extension';
|
||||
import { setCustomIntegrations, setCustomIntegrationsStart } from './services/custom_integrations';
|
||||
import { getFleetDeepLinks } from './deep_links';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
export type { FleetConfigType } from '../common/types';
|
||||
|
||||
|
@ -193,7 +194,7 @@ export class FleetPlugin implements Plugin<FleetSetup, FleetStart, FleetSetupDep
|
|||
...startDepsServices,
|
||||
storage: this.storage,
|
||||
cloud,
|
||||
authz: await fleetStart.authz,
|
||||
authz: fleetStart.authz,
|
||||
};
|
||||
const { renderApp, teardownIntegrations } = await import('./applications/integrations');
|
||||
|
||||
|
@ -236,7 +237,7 @@ export class FleetPlugin implements Plugin<FleetSetup, FleetStart, FleetSetupDep
|
|||
...startDepsServices,
|
||||
storage: this.storage,
|
||||
cloud,
|
||||
authz: await fleetStart.authz,
|
||||
authz: fleetStart.authz,
|
||||
};
|
||||
const { renderApp, teardownFleet } = await import('./applications/fleet');
|
||||
const unmount = renderApp(startServices, params, config, kibanaVersion, extensions);
|
||||
|
|
|
@ -106,5 +106,7 @@
|
|||
"@kbn/code-editor",
|
||||
"@kbn/core-test-helpers-model-versions",
|
||||
"@kbn/zod-helpers",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/react-kibana-context-render",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue