mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Use KibanaThemeProvider
for security/spaces apps (#119124)
This commit is contained in:
parent
3c17852eb1
commit
e5b279f318
39 changed files with 532 additions and 218 deletions
|
@ -9,7 +9,7 @@
|
|||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import { ClusterAddressForm } from './cluster_address_form';
|
||||
import { Providers } from './plugin';
|
||||
|
@ -21,6 +21,8 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
|||
describe('ClusterAddressForm', () => {
|
||||
jest.setTimeout(20_000);
|
||||
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
|
||||
it('calls enrollment API when submitting form', async () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.post.mockResolvedValue({});
|
||||
|
@ -28,7 +30,7 @@ describe('ClusterAddressForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<ClusterAddressForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -52,7 +54,7 @@ describe('ClusterAddressForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findAllByText, findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<ClusterAddressForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import { ClusterConfigurationForm } from './cluster_configuration_form';
|
||||
import { Providers } from './plugin';
|
||||
|
@ -21,6 +21,8 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
|||
describe('ClusterConfigurationForm', () => {
|
||||
jest.setTimeout(20_000);
|
||||
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
|
||||
it('calls enrollment API for https addresses when submitting form', async () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.post.mockResolvedValue({});
|
||||
|
@ -28,7 +30,7 @@ describe('ClusterConfigurationForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<ClusterConfigurationForm
|
||||
host="https://localhost:9200"
|
||||
authRequired
|
||||
|
@ -78,7 +80,7 @@ describe('ClusterConfigurationForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findByRole } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<ClusterConfigurationForm
|
||||
host="http://localhost:9200"
|
||||
authRequired={false}
|
||||
|
@ -107,7 +109,7 @@ describe('ClusterConfigurationForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findAllByText, findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<ClusterConfigurationForm
|
||||
host="https://localhost:9200"
|
||||
authRequired
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import type { EnrollmentToken } from '../common';
|
||||
import { decodeEnrollmentToken, EnrollmentTokenForm } from './enrollment_token_form';
|
||||
|
@ -29,6 +29,8 @@ const token: EnrollmentToken = {
|
|||
describe('EnrollmentTokenForm', () => {
|
||||
jest.setTimeout(20_000);
|
||||
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
|
||||
it('calls enrollment API when submitting form', async () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.post.mockResolvedValue({});
|
||||
|
@ -36,7 +38,7 @@ describe('EnrollmentTokenForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<EnrollmentTokenForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -62,7 +64,7 @@ describe('EnrollmentTokenForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findAllByText, findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<EnrollmentTokenForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
import type { FunctionComponent } from 'react';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import type { CoreSetup, CoreStart, Plugin } from 'src/core/public';
|
||||
import type { CoreSetup, CoreStart, CoreTheme, Plugin } from 'src/core/public';
|
||||
|
||||
import { App } from './app';
|
||||
import { KibanaThemeProvider } from './theme'; // TODO: replace this with the one exported from `kibana_react` after https://github.com/elastic/kibana/issues/119204 is implemented.
|
||||
import { KibanaProvider } from './use_kibana';
|
||||
import { VerificationProvider } from './use_verification';
|
||||
|
||||
|
@ -24,7 +26,7 @@ export class InteractiveSetupPlugin implements Plugin<void, void, {}, {}> {
|
|||
title: 'Configure Elastic to get started',
|
||||
appRoute: '/',
|
||||
chromeless: true,
|
||||
mount: async (params) => {
|
||||
mount: async ({ element, theme$ }) => {
|
||||
const url = new URL(window.location.href);
|
||||
const defaultCode = url.searchParams.get('code') || undefined;
|
||||
const onSuccess = () => {
|
||||
|
@ -34,12 +36,12 @@ export class InteractiveSetupPlugin implements Plugin<void, void, {}, {}> {
|
|||
const [services] = await core.getStartServices();
|
||||
|
||||
ReactDOM.render(
|
||||
<Providers defaultCode={defaultCode} services={services}>
|
||||
<Providers defaultCode={defaultCode} services={services} theme$={theme$}>
|
||||
<App onSuccess={onSuccess} />
|
||||
</Providers>,
|
||||
params.element
|
||||
element
|
||||
);
|
||||
return () => ReactDOM.unmountComponentAtNode(params.element);
|
||||
return () => ReactDOM.unmountComponentAtNode(element);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -49,17 +51,21 @@ export class InteractiveSetupPlugin implements Plugin<void, void, {}, {}> {
|
|||
|
||||
export interface ProvidersProps {
|
||||
services: CoreStart;
|
||||
theme$: Observable<CoreTheme>;
|
||||
defaultCode?: string;
|
||||
}
|
||||
|
||||
export const Providers: FunctionComponent<ProvidersProps> = ({
|
||||
defaultCode,
|
||||
services,
|
||||
theme$,
|
||||
children,
|
||||
}) => (
|
||||
<I18nProvider>
|
||||
<KibanaProvider services={services}>
|
||||
<VerificationProvider defaultCode={defaultCode}>{children}</VerificationProvider>
|
||||
</KibanaProvider>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<KibanaProvider services={services}>
|
||||
<VerificationProvider defaultCode={defaultCode}>{children}</VerificationProvider>
|
||||
</KibanaProvider>
|
||||
</KibanaThemeProvider>
|
||||
</I18nProvider>
|
||||
);
|
||||
|
|
9
src/plugins/interactive_setup/public/theme/index.ts
Normal file
9
src/plugins/interactive_setup/public/theme/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { KibanaThemeProvider } from './kibana_theme_provider';
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import type { ReactWrapper } from 'enzyme';
|
||||
import type { FC } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { BehaviorSubject, of } from 'rxjs';
|
||||
|
||||
import { mountWithIntl } from '@kbn/test/jest';
|
||||
import type { CoreTheme } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from './kibana_theme_provider';
|
||||
|
||||
describe('KibanaThemeProvider', () => {
|
||||
let euiTheme: ReturnType<typeof useEuiTheme> | undefined;
|
||||
|
||||
beforeEach(() => {
|
||||
euiTheme = undefined;
|
||||
});
|
||||
|
||||
const flushPromises = async () => {
|
||||
await new Promise<void>(async (resolve, reject) => {
|
||||
try {
|
||||
setImmediate(() => resolve());
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const InnerComponent: FC = () => {
|
||||
const theme = useEuiTheme();
|
||||
useEffect(() => {
|
||||
euiTheme = theme;
|
||||
}, [theme]);
|
||||
return <div>foo</div>;
|
||||
};
|
||||
|
||||
const refresh = async (wrapper: ReactWrapper<unknown>) => {
|
||||
await act(async () => {
|
||||
await flushPromises();
|
||||
wrapper.update();
|
||||
});
|
||||
};
|
||||
|
||||
it('exposes the EUI theme provider', async () => {
|
||||
const coreTheme: CoreTheme = { darkMode: true };
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
<KibanaThemeProvider theme$={of(coreTheme)}>
|
||||
<InnerComponent />
|
||||
</KibanaThemeProvider>
|
||||
);
|
||||
|
||||
await refresh(wrapper);
|
||||
|
||||
expect(euiTheme!.colorMode).toEqual('DARK');
|
||||
});
|
||||
|
||||
it('propagates changes of the coreTheme observable', async () => {
|
||||
const coreTheme$ = new BehaviorSubject<CoreTheme>({ darkMode: true });
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
<KibanaThemeProvider theme$={coreTheme$}>
|
||||
<InnerComponent />
|
||||
</KibanaThemeProvider>
|
||||
);
|
||||
|
||||
await refresh(wrapper);
|
||||
|
||||
expect(euiTheme!.colorMode).toEqual('DARK');
|
||||
|
||||
await act(async () => {
|
||||
coreTheme$.next({ darkMode: false });
|
||||
});
|
||||
|
||||
await refresh(wrapper);
|
||||
|
||||
expect(euiTheme!.colorMode).toEqual('LIGHT');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { EuiThemeProvider } from '@elastic/eui';
|
||||
import type { FC } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
import type { CoreTheme } from '../../../../core/public';
|
||||
import { getColorMode } from './utils';
|
||||
|
||||
interface KibanaThemeProviderProps {
|
||||
theme$: Observable<CoreTheme>;
|
||||
}
|
||||
|
||||
const defaultTheme: CoreTheme = {
|
||||
darkMode: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* Copied from the `kibana_react` plugin, remove once https://github.com/elastic/kibana/issues/119204 is implemented.
|
||||
*/
|
||||
export const KibanaThemeProvider: FC<KibanaThemeProviderProps> = ({ theme$, children }) => {
|
||||
const theme = useObservable(theme$, defaultTheme);
|
||||
const colorMode = useMemo(() => getColorMode(theme), [theme]);
|
||||
return <EuiThemeProvider colorMode={colorMode}>{children}</EuiThemeProvider>;
|
||||
};
|
19
src/plugins/interactive_setup/public/theme/utils.test.ts
Normal file
19
src/plugins/interactive_setup/public/theme/utils.test.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { getColorMode } from './utils';
|
||||
|
||||
describe('getColorMode', () => {
|
||||
it('returns the correct `colorMode` when `darkMode` is enabled', () => {
|
||||
expect(getColorMode({ darkMode: true })).toEqual('DARK');
|
||||
});
|
||||
|
||||
it('returns the correct `colorMode` when `darkMode` is disabled', () => {
|
||||
expect(getColorMode({ darkMode: false })).toEqual('LIGHT');
|
||||
});
|
||||
});
|
19
src/plugins/interactive_setup/public/theme/utils.ts
Normal file
19
src/plugins/interactive_setup/public/theme/utils.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { EuiThemeColorMode } from '@elastic/eui/src/services/theme/types';
|
||||
|
||||
import type { CoreTheme } from '../../../../core/public';
|
||||
|
||||
/**
|
||||
* Copied from the `kibana_react` plugin, remove once https://github.com/elastic/kibana/issues/119204 is implemented.
|
||||
*/
|
||||
export const getColorMode = (theme: CoreTheme): EuiThemeColorMode => {
|
||||
// COLOR_MODES_STANDARD is not exported from eui
|
||||
return theme.darkMode ? 'DARK' : 'LIGHT';
|
||||
};
|
|
@ -9,7 +9,7 @@
|
|||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import { Providers } from './plugin';
|
||||
import { VerificationCodeForm } from './verification_code_form';
|
||||
|
@ -21,6 +21,8 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
|||
describe('VerificationCodeForm', () => {
|
||||
jest.setTimeout(20_000);
|
||||
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
|
||||
it('calls enrollment API when submitting form', async () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.post.mockResolvedValue({});
|
||||
|
@ -28,7 +30,7 @@ describe('VerificationCodeForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<VerificationCodeForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -65,7 +67,7 @@ describe('VerificationCodeForm', () => {
|
|||
const onSuccess = jest.fn();
|
||||
|
||||
const { findAllByText, findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart}>
|
||||
<Providers services={coreStart} theme$={theme$}>
|
||||
<VerificationCodeForm onSuccess={onSuccess} />
|
||||
</Providers>
|
||||
);
|
||||
|
|
|
@ -21,6 +21,9 @@ const defaultTheme: CoreTheme = {
|
|||
darkMode: false,
|
||||
};
|
||||
|
||||
// IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
|
||||
// That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.
|
||||
|
||||
export const KibanaThemeProvider: FC<KibanaThemeProviderProps> = ({ theme$, children }) => {
|
||||
const theme = useObservable(theme$, defaultTheme);
|
||||
const colorMode = useMemo(() => getColorMode(theme), [theme]);
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
import type { EuiThemeColorMode } from '@elastic/eui/src/services/theme/types';
|
||||
import type { CoreTheme } from '../../../../core/public';
|
||||
|
||||
// IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
|
||||
// That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.
|
||||
|
||||
export const getColorMode = (theme: CoreTheme): EuiThemeColorMode => {
|
||||
// COLOR_MODES_STANDARD is not exported from eui
|
||||
return theme.darkMode ? 'DARK' : 'LIGHT';
|
||||
|
|
|
@ -43,7 +43,6 @@ describe('accountManagementApp', () => {
|
|||
coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]);
|
||||
|
||||
const authcMock = securityMock.createSetup().authc;
|
||||
const containerMock = document.createElement('div');
|
||||
|
||||
accountManagementApp.create({
|
||||
application: coreSetupMock.application,
|
||||
|
@ -52,14 +51,15 @@ describe('accountManagementApp', () => {
|
|||
});
|
||||
|
||||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
|
||||
await (mount as AppMount)({
|
||||
element: containerMock,
|
||||
const appMountParams = {
|
||||
element: document.createElement('div'),
|
||||
appBasePath: '',
|
||||
onAppLeave: jest.fn(),
|
||||
setHeaderActionMenu: jest.fn(),
|
||||
history: scopedHistoryMock.create(),
|
||||
theme$: themeServiceMock.createTheme$(),
|
||||
});
|
||||
};
|
||||
await (mount as AppMount)(appMountParams);
|
||||
|
||||
expect(coreStartMock.chrome.setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(coreStartMock.chrome.setBreadcrumbs).toHaveBeenCalledWith([
|
||||
|
@ -68,10 +68,14 @@ describe('accountManagementApp', () => {
|
|||
|
||||
const mockRenderApp = jest.requireMock('./account_management_page').renderAccountManagementPage;
|
||||
expect(mockRenderApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(coreStartMock.i18n, containerMock, {
|
||||
userAPIClient: expect.any(UserAPIClient),
|
||||
authc: authcMock,
|
||||
notifications: coreStartMock.notifications,
|
||||
});
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(
|
||||
coreStartMock.i18n,
|
||||
{ element: appMountParams.element, theme$: appMountParams.theme$ },
|
||||
{
|
||||
userAPIClient: expect.any(UserAPIClient),
|
||||
authc: authcMock,
|
||||
notifications: coreStartMock.notifications,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,18 +28,22 @@ export const accountManagementApp = Object.freeze({
|
|||
title,
|
||||
navLinkStatus: AppNavLinkStatus.hidden,
|
||||
appRoute: '/security/account',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
async mount({ element, theme$ }: AppMountParameters) {
|
||||
const [[coreStart], { renderAccountManagementPage }, { UserAPIClient }] = await Promise.all(
|
||||
[getStartServices(), import('./account_management_page'), import('../management')]
|
||||
);
|
||||
|
||||
coreStart.chrome.setBreadcrumbs([{ text: title }]);
|
||||
|
||||
return renderAccountManagementPage(coreStart.i18n, element, {
|
||||
authc,
|
||||
notifications: coreStart.notifications,
|
||||
userAPIClient: new UserAPIClient(coreStart.http),
|
||||
});
|
||||
return renderAccountManagementPage(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{
|
||||
authc,
|
||||
notifications: coreStart.notifications,
|
||||
userAPIClient: new UserAPIClient(coreStart.http),
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -11,8 +11,9 @@ import ReactDOM from 'react-dom';
|
|||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import type { CoreStart, NotificationsStart } from 'src/core/public';
|
||||
import type { AppMountParameters, CoreStart, NotificationsStart } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||
import type { AuthenticatedUser } from '../../common/model';
|
||||
import { getUserDisplayName } from '../../common/model';
|
||||
import type { AuthenticationServiceSetup } from '../authentication';
|
||||
|
@ -67,12 +68,14 @@ export const AccountManagementPage = ({ userAPIClient, authc, notifications }: P
|
|||
|
||||
export function renderAccountManagementPage(
|
||||
i18nStart: CoreStart['i18n'],
|
||||
element: Element,
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<AccountManagementPage {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<AccountManagementPage {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -37,7 +37,6 @@ describe('accessAgreementApp', () => {
|
|||
const coreSetupMock = coreMock.createSetup();
|
||||
const coreStartMock = coreMock.createStart();
|
||||
coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]);
|
||||
const containerMock = document.createElement('div');
|
||||
|
||||
accessAgreementApp.create({
|
||||
application: coreSetupMock.application,
|
||||
|
@ -45,21 +44,26 @@ describe('accessAgreementApp', () => {
|
|||
});
|
||||
|
||||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
|
||||
await (mount as AppMount)({
|
||||
element: containerMock,
|
||||
const appMountParams = {
|
||||
element: document.createElement('div'),
|
||||
appBasePath: '',
|
||||
onAppLeave: jest.fn(),
|
||||
setHeaderActionMenu: jest.fn(),
|
||||
history: scopedHistoryMock.create(),
|
||||
theme$: themeServiceMock.createTheme$(),
|
||||
});
|
||||
};
|
||||
await (mount as AppMount)(appMountParams);
|
||||
|
||||
const mockRenderApp = jest.requireMock('./access_agreement_page').renderAccessAgreementPage;
|
||||
expect(mockRenderApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(coreStartMock.i18n, containerMock, {
|
||||
http: coreStartMock.http,
|
||||
notifications: coreStartMock.notifications,
|
||||
fatalErrors: coreStartMock.fatalErrors,
|
||||
});
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(
|
||||
coreStartMock.i18n,
|
||||
{ element: appMountParams.element, theme$: appMountParams.theme$ },
|
||||
{
|
||||
http: coreStartMock.http,
|
||||
notifications: coreStartMock.notifications,
|
||||
fatalErrors: coreStartMock.fatalErrors,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,16 +23,20 @@ export const accessAgreementApp = Object.freeze({
|
|||
}),
|
||||
chromeless: true,
|
||||
appRoute: '/security/access_agreement',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
async mount({ element, theme$ }: AppMountParameters) {
|
||||
const [[coreStart], { renderAccessAgreementPage }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./access_agreement_page'),
|
||||
]);
|
||||
return renderAccessAgreementPage(coreStart.i18n, element, {
|
||||
http: coreStart.http,
|
||||
notifications: coreStart.notifications,
|
||||
fatalErrors: coreStart.fatalErrors,
|
||||
});
|
||||
return renderAccessAgreementPage(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{
|
||||
http: coreStart.http,
|
||||
notifications: coreStart.notifications,
|
||||
fatalErrors: coreStart.fatalErrors,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -23,8 +23,15 @@ import ReactMarkdown from 'react-markdown';
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { CoreStart, FatalErrorsStart, HttpStart, NotificationsStart } from 'src/core/public';
|
||||
import type {
|
||||
AppMountParameters,
|
||||
CoreStart,
|
||||
FatalErrorsStart,
|
||||
HttpStart,
|
||||
NotificationsStart,
|
||||
} from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { parseNext } from '../../../common/parse_next';
|
||||
import { AuthenticationStatePage } from '../components';
|
||||
|
||||
|
@ -122,12 +129,14 @@ export function AccessAgreementPage({ http, fatalErrors, notifications }: Props)
|
|||
|
||||
export function renderAccessAgreementPage(
|
||||
i18nStart: CoreStart['i18n'],
|
||||
element: Element,
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<AccessAgreementPage {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<AccessAgreementPage {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -38,24 +38,25 @@ describe('loggedOutApp', () => {
|
|||
const coreStartMock = coreMock.createStart();
|
||||
coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]);
|
||||
|
||||
const containerMock = document.createElement('div');
|
||||
|
||||
loggedOutApp.create(coreSetupMock);
|
||||
|
||||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
|
||||
await (mount as AppMount)({
|
||||
element: containerMock,
|
||||
const appMountParams = {
|
||||
element: document.createElement('div'),
|
||||
appBasePath: '',
|
||||
onAppLeave: jest.fn(),
|
||||
setHeaderActionMenu: jest.fn(),
|
||||
history: scopedHistoryMock.create(),
|
||||
theme$: themeServiceMock.createTheme$(),
|
||||
});
|
||||
};
|
||||
await (mount as AppMount)(appMountParams);
|
||||
|
||||
const mockRenderApp = jest.requireMock('./logged_out_page').renderLoggedOutPage;
|
||||
expect(mockRenderApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(coreStartMock.i18n, containerMock, {
|
||||
basePath: coreStartMock.http.basePath,
|
||||
});
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(
|
||||
coreStartMock.i18n,
|
||||
{ element: appMountParams.element, theme$: appMountParams.theme$ },
|
||||
{ basePath: coreStartMock.http.basePath }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,12 +28,16 @@ export const loggedOutApp = Object.freeze({
|
|||
title: i18n.translate('xpack.security.loggedOutAppTitle', { defaultMessage: 'Logged out' }),
|
||||
chromeless: true,
|
||||
appRoute: '/security/logged_out',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
async mount({ element, theme$ }: AppMountParameters) {
|
||||
const [[coreStart], { renderLoggedOutPage }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./logged_out_page'),
|
||||
]);
|
||||
return renderLoggedOutPage(coreStart.i18n, element, { basePath: coreStart.http.basePath });
|
||||
return renderLoggedOutPage(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{ basePath: coreStart.http.basePath }
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -10,8 +10,9 @@ import React from 'react';
|
|||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { CoreStart, IBasePath } from 'src/core/public';
|
||||
import type { AppMountParameters, CoreStart, IBasePath } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { parseNext } from '../../../common/parse_next';
|
||||
import { AuthenticationStatePage } from '../components';
|
||||
|
||||
|
@ -36,10 +37,16 @@ export function LoggedOutPage({ basePath }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export function renderLoggedOutPage(i18nStart: CoreStart['i18n'], element: Element, props: Props) {
|
||||
export function renderLoggedOutPage(
|
||||
i18nStart: CoreStart['i18n'],
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<LoggedOutPage {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<LoggedOutPage {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -40,7 +40,6 @@ describe('loginApp', () => {
|
|||
const coreSetupMock = coreMock.createSetup();
|
||||
const coreStartMock = coreMock.createStart();
|
||||
coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]);
|
||||
const containerMock = document.createElement('div');
|
||||
|
||||
loginApp.create({
|
||||
...coreSetupMock,
|
||||
|
@ -48,22 +47,27 @@ describe('loginApp', () => {
|
|||
});
|
||||
|
||||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
|
||||
await (mount as AppMount)({
|
||||
element: containerMock,
|
||||
const appMountParams = {
|
||||
element: document.createElement('div'),
|
||||
appBasePath: '',
|
||||
onAppLeave: jest.fn(),
|
||||
setHeaderActionMenu: jest.fn(),
|
||||
history: scopedHistoryMock.create(),
|
||||
theme$: themeServiceMock.createTheme$(),
|
||||
});
|
||||
};
|
||||
await (mount as AppMount)(appMountParams);
|
||||
|
||||
const mockRenderApp = jest.requireMock('./login_page').renderLoginPage;
|
||||
expect(mockRenderApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(coreStartMock.i18n, containerMock, {
|
||||
http: coreStartMock.http,
|
||||
notifications: coreStartMock.notifications,
|
||||
fatalErrors: coreStartMock.fatalErrors,
|
||||
loginAssistanceMessage: 'some-message',
|
||||
});
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(
|
||||
coreStartMock.i18n,
|
||||
{ element: appMountParams.element, theme$: appMountParams.theme$ },
|
||||
{
|
||||
http: coreStartMock.http,
|
||||
notifications: coreStartMock.notifications,
|
||||
fatalErrors: coreStartMock.fatalErrors,
|
||||
loginAssistanceMessage: 'some-message',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,17 +31,21 @@ export const loginApp = Object.freeze({
|
|||
title: i18n.translate('xpack.security.loginAppTitle', { defaultMessage: 'Login' }),
|
||||
chromeless: true,
|
||||
appRoute: '/login',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
async mount({ element, theme$ }: AppMountParameters) {
|
||||
const [[coreStart], { renderLoginPage }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./login_page'),
|
||||
]);
|
||||
return renderLoginPage(coreStart.i18n, element, {
|
||||
http: coreStart.http,
|
||||
notifications: coreStart.notifications,
|
||||
fatalErrors: coreStart.fatalErrors,
|
||||
loginAssistanceMessage: config.loginAssistanceMessage,
|
||||
});
|
||||
return renderLoginPage(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{
|
||||
http: coreStart.http,
|
||||
notifications: coreStart.notifications,
|
||||
fatalErrors: coreStart.fatalErrors,
|
||||
loginAssistanceMessage: config.loginAssistanceMessage,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -15,8 +15,15 @@ import { BehaviorSubject } from 'rxjs';
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { CoreStart, FatalErrorsStart, HttpStart, NotificationsStart } from 'src/core/public';
|
||||
import type {
|
||||
AppMountParameters,
|
||||
CoreStart,
|
||||
FatalErrorsStart,
|
||||
HttpStart,
|
||||
NotificationsStart,
|
||||
} from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
AUTH_PROVIDER_HINT_QUERY_STRING_PARAMETER,
|
||||
LOGOUT_REASON_QUERY_STRING_PARAMETER,
|
||||
|
@ -251,10 +258,16 @@ export class LoginPage extends Component<Props, State> {
|
|||
};
|
||||
}
|
||||
|
||||
export function renderLoginPage(i18nStart: CoreStart['i18n'], element: Element, props: Props) {
|
||||
export function renderLoginPage(
|
||||
i18nStart: CoreStart['i18n'],
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<LoginPage {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<LoginPage {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -41,8 +41,6 @@ describe('overwrittenSessionApp', () => {
|
|||
coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]);
|
||||
|
||||
const authcMock = securityMock.createSetup().authc;
|
||||
const containerMock = document.createElement('div');
|
||||
|
||||
overwrittenSessionApp.create({
|
||||
application: coreSetupMock.application,
|
||||
getStartServices: coreSetupMock.getStartServices,
|
||||
|
@ -50,22 +48,24 @@ describe('overwrittenSessionApp', () => {
|
|||
});
|
||||
|
||||
const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
|
||||
await (mount as AppMount)({
|
||||
element: containerMock,
|
||||
const appMountParams = {
|
||||
element: document.createElement('div'),
|
||||
appBasePath: '',
|
||||
onAppLeave: jest.fn(),
|
||||
setHeaderActionMenu: jest.fn(),
|
||||
history: scopedHistoryMock.create(),
|
||||
theme$: themeServiceMock.createTheme$(),
|
||||
});
|
||||
};
|
||||
await (mount as AppMount)(appMountParams);
|
||||
|
||||
const mockRenderApp = jest.requireMock(
|
||||
'./overwritten_session_page'
|
||||
).renderOverwrittenSessionPage;
|
||||
expect(mockRenderApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(coreStartMock.i18n, containerMock, {
|
||||
authc: authcMock,
|
||||
basePath: coreStartMock.http.basePath,
|
||||
});
|
||||
expect(mockRenderApp).toHaveBeenCalledWith(
|
||||
coreStartMock.i18n,
|
||||
{ element: appMountParams.element, theme$: appMountParams.theme$ },
|
||||
{ authc: authcMock, basePath: coreStartMock.http.basePath }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,15 +26,19 @@ export const overwrittenSessionApp = Object.freeze({
|
|||
}),
|
||||
chromeless: true,
|
||||
appRoute: '/security/overwritten_session',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
async mount({ element, theme$ }: AppMountParameters) {
|
||||
const [[coreStart], { renderOverwrittenSessionPage }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./overwritten_session_page'),
|
||||
]);
|
||||
return renderOverwrittenSessionPage(coreStart.i18n, element, {
|
||||
authc,
|
||||
basePath: coreStart.http.basePath,
|
||||
});
|
||||
return renderOverwrittenSessionPage(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{
|
||||
authc,
|
||||
basePath: coreStart.http.basePath,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -10,8 +10,9 @@ import React, { useEffect, useState } from 'react';
|
|||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { CoreStart, IBasePath } from 'src/core/public';
|
||||
import type { AppMountParameters, CoreStart, IBasePath } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { parseNext } from '../../../common/parse_next';
|
||||
import type { AuthenticationServiceSetup } from '../authentication_service';
|
||||
import { AuthenticationStatePage } from '../components';
|
||||
|
@ -53,12 +54,14 @@ export function OverwrittenSessionPage({ authc, basePath }: Props) {
|
|||
|
||||
export function renderOverwrittenSessionPage(
|
||||
i18nStart: CoreStart['i18n'],
|
||||
element: Element,
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<OverwrittenSessionPage {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<OverwrittenSessionPage {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { render } from '@testing-library/react';
|
|||
import { createMemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from '../../../../../../../src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from '../../../../../../../src/core/public/mocks';
|
||||
import { mockAuthenticatedUser } from '../../../../common/model/authenticated_user.mock';
|
||||
import { securityMock } from '../../../mocks';
|
||||
import { Providers } from '../api_keys_management_app';
|
||||
|
@ -33,6 +33,7 @@ describe('APIKeysGridPage', () => {
|
|||
const consoleWarnMock = jest.spyOn(console, 'error').mockImplementation();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
const apiClientMock = apiKeysAPIClientMock.create();
|
||||
const { authc } = securityMock.createSetup();
|
||||
|
||||
|
@ -85,7 +86,7 @@ describe('APIKeysGridPage', () => {
|
|||
const history = createMemoryHistory({ initialEntries: ['/'] });
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<APIKeysGridPage
|
||||
apiKeysAPIClient={apiClientMock}
|
||||
notifications={coreStart.notifications}
|
||||
|
@ -113,7 +114,7 @@ describe('APIKeysGridPage', () => {
|
|||
});
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<APIKeysGridPage
|
||||
apiKeysAPIClient={apiClientMock}
|
||||
notifications={coreStart.notifications}
|
||||
|
@ -135,7 +136,7 @@ describe('APIKeysGridPage', () => {
|
|||
});
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<APIKeysGridPage
|
||||
apiKeysAPIClient={apiClientMock}
|
||||
notifications={coreStart.notifications}
|
||||
|
@ -159,7 +160,7 @@ describe('APIKeysGridPage', () => {
|
|||
const history = createMemoryHistory({ initialEntries: ['/'] });
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<APIKeysGridPage
|
||||
apiKeysAPIClient={apiClientMock}
|
||||
notifications={coreStart.notifications}
|
||||
|
|
|
@ -10,12 +10,20 @@ import type { FunctionComponent } from 'react';
|
|||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Router } from 'react-router-dom';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
import type { CoreStart, StartServicesAccessor } from '../../../../../../src/core/public';
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import type {
|
||||
CoreStart,
|
||||
CoreTheme,
|
||||
StartServicesAccessor,
|
||||
} from '../../../../../../src/core/public';
|
||||
import {
|
||||
KibanaContextProvider,
|
||||
KibanaThemeProvider,
|
||||
} from '../../../../../../src/plugins/kibana_react/public';
|
||||
import type { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
||||
import type { AuthenticationServiceSetup } from '../../authentication';
|
||||
import type { BreadcrumbsChangeHandler } from '../../components/breadcrumb';
|
||||
|
@ -41,7 +49,7 @@ export const apiKeysManagementApp = Object.freeze({
|
|||
title: i18n.translate('xpack.security.management.apiKeysTitle', {
|
||||
defaultMessage: 'API keys',
|
||||
}),
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
async mount({ element, theme$, setBreadcrumbs, history }) {
|
||||
const [[coreStart], { APIKeysGridPage }, { APIKeysAPIClient }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./api_keys_grid'),
|
||||
|
@ -51,6 +59,7 @@ export const apiKeysManagementApp = Object.freeze({
|
|||
render(
|
||||
<Providers
|
||||
services={coreStart}
|
||||
theme$={theme$}
|
||||
history={history}
|
||||
authc={authc}
|
||||
onChange={createBreadcrumbsChangeHandler(coreStart.chrome, setBreadcrumbs)}
|
||||
|
@ -81,6 +90,7 @@ export const apiKeysManagementApp = Object.freeze({
|
|||
|
||||
export interface ProvidersProps {
|
||||
services: CoreStart;
|
||||
theme$: Observable<CoreTheme>;
|
||||
history: History;
|
||||
authc: AuthenticationServiceSetup;
|
||||
onChange?: BreadcrumbsChangeHandler;
|
||||
|
@ -88,6 +98,7 @@ export interface ProvidersProps {
|
|||
|
||||
export const Providers: FunctionComponent<ProvidersProps> = ({
|
||||
services,
|
||||
theme$,
|
||||
history,
|
||||
authc,
|
||||
onChange,
|
||||
|
@ -96,9 +107,11 @@ export const Providers: FunctionComponent<ProvidersProps> = ({
|
|||
<KibanaContextProvider services={services}>
|
||||
<AuthenticationProvider authc={authc}>
|
||||
<I18nProvider>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider onChange={onChange}>{children}</BreadcrumbsProvider>
|
||||
</Router>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider onChange={onChange}>{children}</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</KibanaThemeProvider>
|
||||
</I18nProvider>
|
||||
</AuthenticationProvider>
|
||||
</KibanaContextProvider>
|
||||
|
|
|
@ -13,7 +13,10 @@ import { i18n } from '@kbn/i18n';
|
|||
import type { StartServicesAccessor } from 'src/core/public';
|
||||
import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
||||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
KibanaContextProvider,
|
||||
KibanaThemeProvider,
|
||||
} from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbsProvider,
|
||||
|
@ -37,7 +40,7 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
id: this.id,
|
||||
order: 40,
|
||||
title,
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
async mount({ element, theme$, setBreadcrumbs, history }) {
|
||||
const [
|
||||
[core],
|
||||
{ RoleMappingsGridPage },
|
||||
|
@ -90,30 +93,32 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
render(
|
||||
<KibanaContextProvider services={core}>
|
||||
<core.i18n.Context>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(core.chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RoleMappingsGridPage
|
||||
notifications={core.notifications}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
navigateToApp={core.application.navigateToApp}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:name?">
|
||||
<EditRoleMappingsPageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:name">
|
||||
<EditRoleMappingsPageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(core.chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RoleMappingsGridPage
|
||||
notifications={core.notifications}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
navigateToApp={core.application.navigateToApp}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:name?">
|
||||
<EditRoleMappingsPageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:name">
|
||||
<EditRoleMappingsPageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</KibanaThemeProvider>
|
||||
</core.i18n.Context>
|
||||
</KibanaContextProvider>,
|
||||
element
|
||||
|
|
|
@ -13,7 +13,10 @@ import { i18n } from '@kbn/i18n';
|
|||
import type { FatalErrorsSetup, StartServicesAccessor } from 'src/core/public';
|
||||
import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
||||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
KibanaContextProvider,
|
||||
KibanaThemeProvider,
|
||||
} from '../../../../../../src/plugins/kibana_react/public';
|
||||
import type { SecurityLicense } from '../../../common/licensing';
|
||||
import {
|
||||
Breadcrumb,
|
||||
|
@ -39,7 +42,7 @@ export const rolesManagementApp = Object.freeze({
|
|||
id: this.id,
|
||||
order: 20,
|
||||
title,
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
async mount({ element, theme$, setBreadcrumbs, history }) {
|
||||
const [
|
||||
[startServices, { data, features, spaces }],
|
||||
{ RolesGridPage },
|
||||
|
@ -116,27 +119,29 @@ export const rolesManagementApp = Object.freeze({
|
|||
render(
|
||||
<KibanaContextProvider services={startServices}>
|
||||
<i18nStart.Context>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RolesGridPage
|
||||
notifications={notifications}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
history={history}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:roleName?">
|
||||
<EditRolePageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:roleName">
|
||||
<EditRolePageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RolesGridPage
|
||||
notifications={notifications}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
history={history}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:roleName?">
|
||||
<EditRolePageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:roleName">
|
||||
<EditRolePageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>
|
||||
</KibanaContextProvider>,
|
||||
element
|
||||
|
|
|
@ -9,7 +9,7 @@ import { fireEvent, render, waitFor, within } from '@testing-library/react';
|
|||
import { createMemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import { securityMock } from '../../../mocks';
|
||||
import { Providers } from '../users_management_app';
|
||||
|
@ -22,6 +22,8 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
|||
describe('CreateUserPage', () => {
|
||||
jest.setTimeout(15_000);
|
||||
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
|
||||
it('creates user when submitting form and redirects back', async () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
const history = createMemoryHistory({ initialEntries: ['/create'] });
|
||||
|
@ -29,7 +31,7 @@ describe('CreateUserPage', () => {
|
|||
coreStart.http.post.mockResolvedValue({});
|
||||
|
||||
const { findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<CreateUserPage />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -72,7 +74,7 @@ describe('CreateUserPage', () => {
|
|||
]);
|
||||
|
||||
const { findAllByText, findByRole, findByLabelText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<CreateUserPage />
|
||||
</Providers>
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { fireEvent, render } from '@testing-library/react';
|
|||
import { createMemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { coreMock, themeServiceMock } from 'src/core/public/mocks';
|
||||
|
||||
import { securityMock } from '../../../mocks';
|
||||
import { Providers } from '../users_management_app';
|
||||
|
@ -25,6 +25,7 @@ const userMock = {
|
|||
|
||||
describe('EditUserPage', () => {
|
||||
const coreStart = coreMock.createStart();
|
||||
const theme$ = themeServiceMock.createTheme$();
|
||||
let history = createMemoryHistory({ initialEntries: ['/edit/jdoe'] });
|
||||
const authc = securityMock.createSetup().authc;
|
||||
|
||||
|
@ -46,7 +47,7 @@ describe('EditUserPage', () => {
|
|||
coreStart.http.get.mockResolvedValueOnce([]);
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<EditUserPage username={userMock.username} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -66,7 +67,7 @@ describe('EditUserPage', () => {
|
|||
coreStart.http.get.mockResolvedValueOnce([]);
|
||||
|
||||
const { findByRole, findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<EditUserPage username={userMock.username} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -87,7 +88,7 @@ describe('EditUserPage', () => {
|
|||
coreStart.http.get.mockResolvedValueOnce([]);
|
||||
|
||||
const { findByRole, findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<EditUserPage username={userMock.username} />
|
||||
</Providers>
|
||||
);
|
||||
|
@ -117,7 +118,7 @@ describe('EditUserPage', () => {
|
|||
]);
|
||||
|
||||
const { findByText } = render(
|
||||
<Providers services={coreStart} authc={authc} history={history}>
|
||||
<Providers services={coreStart} theme$={theme$} authc={authc} history={history}>
|
||||
<EditUserPage username={userMock.username} />
|
||||
</Providers>
|
||||
);
|
||||
|
|
|
@ -11,13 +11,17 @@ import React from 'react';
|
|||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import type { RouteComponentProps } from 'react-router-dom';
|
||||
import { Redirect, Route, Router, Switch } from 'react-router-dom';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import type { CoreStart, StartServicesAccessor } from 'src/core/public';
|
||||
import type { CoreStart, CoreTheme, StartServicesAccessor } from 'src/core/public';
|
||||
import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
||||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
KibanaContextProvider,
|
||||
KibanaThemeProvider,
|
||||
} from '../../../../../../src/plugins/kibana_react/public';
|
||||
import type { AuthenticationServiceSetup } from '../../authentication';
|
||||
import type { BreadcrumbsChangeHandler } from '../../components/breadcrumb';
|
||||
import {
|
||||
|
@ -48,7 +52,7 @@ export const usersManagementApp = Object.freeze({
|
|||
id: this.id,
|
||||
order: 10,
|
||||
title,
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
async mount({ element, theme$, setBreadcrumbs, history }) {
|
||||
const [
|
||||
[coreStart],
|
||||
{ UsersGridPage },
|
||||
|
@ -66,6 +70,7 @@ export const usersManagementApp = Object.freeze({
|
|||
render(
|
||||
<Providers
|
||||
services={coreStart}
|
||||
theme$={theme$}
|
||||
history={history}
|
||||
authc={authc}
|
||||
onChange={createBreadcrumbsChangeHandler(coreStart.chrome, setBreadcrumbs)}
|
||||
|
@ -128,6 +133,7 @@ export const usersManagementApp = Object.freeze({
|
|||
|
||||
export interface ProvidersProps {
|
||||
services: CoreStart;
|
||||
theme$: Observable<CoreTheme>;
|
||||
history: History;
|
||||
authc: AuthenticationServiceSetup;
|
||||
onChange?: BreadcrumbsChangeHandler;
|
||||
|
@ -135,6 +141,7 @@ export interface ProvidersProps {
|
|||
|
||||
export const Providers: FunctionComponent<ProvidersProps> = ({
|
||||
services,
|
||||
theme$,
|
||||
history,
|
||||
authc,
|
||||
onChange,
|
||||
|
@ -143,9 +150,11 @@ export const Providers: FunctionComponent<ProvidersProps> = ({
|
|||
<KibanaContextProvider services={services}>
|
||||
<AuthenticationProvider authc={authc}>
|
||||
<I18nProvider>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider onChange={onChange}>{children}</BreadcrumbsProvider>
|
||||
</Router>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<Router history={history}>
|
||||
<BreadcrumbsProvider onChange={onChange}>{children}</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</KibanaThemeProvider>
|
||||
</I18nProvider>
|
||||
</AuthenticationProvider>
|
||||
</KibanaContextProvider>
|
||||
|
|
|
@ -14,6 +14,7 @@ import { map, takeUntil } from 'rxjs/operators';
|
|||
|
||||
import type { CoreStart } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||
import type { SecurityLicense } from '../../common/licensing';
|
||||
import type { AuthenticationServiceSetup } from '../authentication';
|
||||
import type { UserMenuLink } from './nav_control_component';
|
||||
|
@ -110,8 +111,9 @@ export class SecurityNavControlService {
|
|||
}
|
||||
|
||||
private registerSecurityNavControl(
|
||||
core: Pick<CoreStart, 'chrome' | 'http' | 'i18n' | 'injectedMetadata' | 'application'>
|
||||
core: Pick<CoreStart, 'chrome' | 'http' | 'i18n' | 'injectedMetadata' | 'application' | 'theme'>
|
||||
) {
|
||||
const { theme$ } = core.theme;
|
||||
const currentUserPromise = this.authc.getCurrentUser();
|
||||
core.chrome.navControls.registerRight({
|
||||
order: 2000,
|
||||
|
@ -126,7 +128,9 @@ export class SecurityNavControlService {
|
|||
};
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<SecurityNavControl {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<SecurityNavControl {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</I18nContext>,
|
||||
el
|
||||
);
|
||||
|
|
|
@ -16,6 +16,7 @@ import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
|||
import { APP_WRAPPER_CLASS } from '../../../../../src/core/public';
|
||||
import {
|
||||
KibanaContextProvider,
|
||||
KibanaThemeProvider,
|
||||
RedirectAppLinks,
|
||||
} from '../../../../../src/plugins/kibana_react/public';
|
||||
import type { Space } from '../../common';
|
||||
|
@ -39,7 +40,7 @@ export const spacesManagementApp = Object.freeze({
|
|||
order: 2,
|
||||
title,
|
||||
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
async mount({ element, theme$, setBreadcrumbs, history }) {
|
||||
const [[coreStart, { features }], { SpacesGridPage }, { ManageSpacePage }] =
|
||||
await Promise.all([getStartServices(), import('./spaces_grid'), import('./edit_space')]);
|
||||
|
||||
|
@ -114,21 +115,23 @@ export const spacesManagementApp = Object.freeze({
|
|||
render(
|
||||
<KibanaContextProvider services={coreStart}>
|
||||
<i18nStart.Context>
|
||||
<RedirectAppLinks application={application} className={APP_WRAPPER_CLASS}>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path={['', '/']} exact>
|
||||
<SpacesGridPageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/create">
|
||||
<CreateSpacePageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/edit/:spaceId">
|
||||
<EditSpacePageWithBreadcrumbs />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</RedirectAppLinks>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<RedirectAppLinks application={application} className={APP_WRAPPER_CLASS}>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path={['', '/']} exact>
|
||||
<SpacesGridPageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/create">
|
||||
<CreateSpacePageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/edit/:spaceId">
|
||||
<EditSpacePageWithBreadcrumbs />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</RedirectAppLinks>
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>
|
||||
</KibanaContextProvider>,
|
||||
element
|
||||
|
|
|
@ -11,10 +11,12 @@ import ReactDOM from 'react-dom';
|
|||
|
||||
import type { CoreStart } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||
import type { SpacesManager } from '../spaces_manager';
|
||||
|
||||
export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreStart) {
|
||||
const I18nContext = core.i18n.Context;
|
||||
const { theme$ } = core.theme;
|
||||
core.chrome.navControls.registerLeft({
|
||||
order: 1000,
|
||||
mount(targetDomElement: HTMLElement) {
|
||||
|
@ -30,15 +32,17 @@ export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreSta
|
|||
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
<Suspense fallback={<EuiLoadingSpinner />}>
|
||||
<LazyNavControlPopover
|
||||
spacesManager={spacesManager}
|
||||
serverBasePath={core.http.basePath.serverBasePath}
|
||||
anchorPosition="downLeft"
|
||||
capabilities={core.application.capabilities}
|
||||
navigateToApp={core.application.navigateToApp}
|
||||
/>
|
||||
</Suspense>
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<Suspense fallback={<EuiLoadingSpinner />}>
|
||||
<LazyNavControlPopover
|
||||
spacesManager={spacesManager}
|
||||
serverBasePath={core.http.basePath.serverBasePath}
|
||||
anchorPosition="downLeft"
|
||||
capabilities={core.application.capabilities}
|
||||
navigateToApp={core.application.navigateToApp}
|
||||
/>
|
||||
</Suspense>
|
||||
</KibanaThemeProvider>
|
||||
</I18nContext>,
|
||||
targetDomElement
|
||||
);
|
||||
|
|
|
@ -27,8 +27,9 @@ import ReactDOM from 'react-dom';
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import type { CoreStart } from 'src/core/public';
|
||||
import type { AppMountParameters, CoreStart } from 'src/core/public';
|
||||
|
||||
import { KibanaThemeProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||
import type { Space } from '../../common';
|
||||
import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../common/constants';
|
||||
import type { SpacesManager } from '../spaces_manager';
|
||||
|
@ -213,12 +214,18 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
};
|
||||
}
|
||||
|
||||
export const renderSpaceSelectorApp = (i18nStart: CoreStart['i18n'], el: Element, props: Props) => {
|
||||
export const renderSpaceSelectorApp = (
|
||||
i18nStart: CoreStart['i18n'],
|
||||
{ element, theme$ }: Pick<AppMountParameters, 'element' | 'theme$'>,
|
||||
props: Props
|
||||
) => {
|
||||
ReactDOM.render(
|
||||
<i18nStart.Context>
|
||||
<SpaceSelector {...props} />
|
||||
<KibanaThemeProvider theme$={theme$}>
|
||||
<SpaceSelector {...props} />
|
||||
</KibanaThemeProvider>
|
||||
</i18nStart.Context>,
|
||||
el
|
||||
element
|
||||
);
|
||||
return () => ReactDOM.unmountComponentAtNode(el);
|
||||
return () => ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
||||
|
|
|
@ -26,15 +26,19 @@ export const spaceSelectorApp = Object.freeze({
|
|||
}),
|
||||
chromeless: true,
|
||||
appRoute: '/spaces/space_selector',
|
||||
mount: async (params: AppMountParameters) => {
|
||||
mount: async ({ element, theme$ }: AppMountParameters) => {
|
||||
const [[coreStart], { renderSpaceSelectorApp }] = await Promise.all([
|
||||
getStartServices(),
|
||||
import('./space_selector'),
|
||||
]);
|
||||
return renderSpaceSelectorApp(coreStart.i18n, params.element, {
|
||||
spacesManager,
|
||||
serverBasePath: coreStart.http.basePath.serverBasePath,
|
||||
});
|
||||
return renderSpaceSelectorApp(
|
||||
coreStart.i18n,
|
||||
{ element, theme$ },
|
||||
{
|
||||
spacesManager,
|
||||
serverBasePath: coreStart.http.basePath.serverBasePath,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue