[SharedUX] Remove usage of deprecated React rendering utilities (#180516)

## Summary

Partially addresses https://github.com/elastic/kibana-team/issues/805

Follows https://github.com/elastic/kibana/pull/180003

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 focuses on code within AppEx-SharedUX. [Reporting changes are
separate](https://github.com/elastic/kibana/pull/).

<img width="1107" alt="image"
src="c0d2ce08-ac35-45a7-8192-0b2256fceb0e">

### 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:
Tim Sullivan 2024-04-17 07:52:41 -07:00 committed by GitHub
parent 4c90777dee
commit e4a32f8f3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
54 changed files with 226 additions and 258 deletions

View file

@ -10,8 +10,6 @@
"requiredPlugins": [
"uiActions"
],
"requiredBundles": [
"kibanaReact"
]
"requiredBundles": []
}
}

View file

@ -8,14 +8,12 @@
import React from 'react';
import { EuiText, EuiModalBody, EuiButton } from '@elastic/eui';
import { OverlayStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { CoreStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD';
interface StartServices {
openModal: OverlayStart['openModal'];
}
type StartServices = Pick<CoreStart, 'overlays' | 'analytics' | 'i18n' | 'theme'>;
export const createHelloWorldActionDefinition = (
getStartServices: () => Promise<StartServices>
@ -24,15 +22,16 @@ export const createHelloWorldActionDefinition = (
type: ACTION_HELLO_WORLD,
getDisplayName: () => 'Hello World!',
execute: async () => {
const { openModal } = await getStartServices();
const overlay = openModal(
const { overlays, ...startServices } = await getStartServices();
const overlay = overlays.openModal(
toMountPoint(
<EuiModalBody>
<EuiText data-test-subj="helloWorldActionText">Hello world!</EuiText>
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
Close
</EuiButton>
</EuiModalBody>
</EuiModalBody>,
startServices
)
);
},

View file

@ -29,14 +29,14 @@ export class UiActionExamplesPlugin
) {
uiActions.registerTrigger(helloWorldTrigger);
const helloWorldAction = createHelloWorldActionDefinition(async () => ({
openModal: (await core.getStartServices())[0].overlays.openModal,
}));
const helloWorldAction = createHelloWorldActionDefinition(
async () => (await core.getStartServices())[0]
);
uiActions.addTriggerAction(helloWorldTrigger.id, helloWorldAction);
}
public start(core: CoreStart, plugins: UiActionExamplesStartDependencies) {}
public start(_core: CoreStart, _plugins: UiActionExamplesStartDependencies) {}
public stop() {}
}

View file

@ -14,8 +14,8 @@
"target/**/*",
],
"kbn_references": [
"@kbn/kibana-react-plugin",
"@kbn/ui-actions-plugin",
"@kbn/core",
"@kbn/react-kibana-mount",
]
}

View file

@ -12,8 +12,6 @@
"uiActionsExamples",
"developerExamples"
],
"requiredBundles": [
"kibanaReact"
]
"requiredBundles": []
}
}

View file

@ -7,10 +7,10 @@
*/
import React from 'react';
import { OverlayStart } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import { EuiFieldText, EuiModalBody, EuiButton } from '@elastic/eui';
import { useState } from 'react';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import {
ActionExecutionContext,
createAction,
@ -102,15 +102,19 @@ function EditUserModal({
);
}
export const createEditUserAction = (getOpenModal: () => Promise<OverlayStart['openModal']>) =>
export const createEditUserAction = (getStartServices: () => Promise<CoreStart>) =>
createAction<UserContext>({
id: ACTION_EDIT_USER,
type: ACTION_EDIT_USER,
getIconType: () => 'pencil',
getDisplayName: () => 'Edit user',
execute: async ({ user, update }) => {
const overlay = (await getOpenModal())(
toMountPoint(<EditUserModal user={user} update={update} close={() => overlay.close()} />)
const { overlays, ...startServices } = await getStartServices();
const overlay = overlays.openModal(
toMountPoint(
<EditUserModal user={user} update={update} close={() => overlay.close()} />,
startServices
)
);
},
});

View file

@ -17,8 +17,8 @@ import {
EuiSpacer,
EuiPageHeader,
} from '@elastic/eui';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { AppMountParameters, OverlayStart } from '@kbn/core/public';
import { TriggerContextExample } from './trigger_context_example';
import { ContextMenuExamples } from './context_menu_examples';
import { Overview } from './overview';
@ -26,10 +26,10 @@ import { HelloWorldExample } from './hello_world_example';
interface Props {
uiActionsStartService: UiActionsStart;
openModal: OverlayStart['openModal'];
core: CoreStart;
}
const ActionsExplorer = ({ uiActionsStartService, openModal }: Props) => {
const ActionsExplorer = ({ uiActionsStartService, core }: Props) => {
return (
<EuiPage>
<EuiPageBody>
@ -42,10 +42,7 @@ const ActionsExplorer = ({ uiActionsStartService, openModal }: Props) => {
<EuiSpacer />
<HelloWorldExample
uiActionsStartService={uiActionsStartService}
openModal={openModal}
/>
<HelloWorldExample uiActionsStartService={uiActionsStartService} startServices={core} />
<EuiSpacer />

View file

@ -9,19 +9,19 @@
import React, { useState } from 'react';
import { EuiButton, EuiSpacer, EuiText, EuiModalBody, EuiLink, EuiSwitch } from '@elastic/eui';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { UiActionsStart, createAction } from '@kbn/ui-actions-plugin/public';
import { OverlayStart } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import { HELLO_WORLD_TRIGGER_ID, ACTION_HELLO_WORLD } from '@kbn/ui-actions-examples-plugin/public';
const DYNAMIC_ACTION_ID = `${ACTION_HELLO_WORLD}-Waldo`;
interface Props {
uiActionsStartService: UiActionsStart;
openModal: OverlayStart['openModal'];
startServices: Pick<CoreStart, 'overlays' | 'analytics' | 'i18n' | 'theme'>;
}
export const HelloWorldExample = ({ uiActionsStartService, openModal }: Props) => {
export const HelloWorldExample = ({ uiActionsStartService, startServices }: Props) => {
const [isChecked, setIsChecked] = useState(false);
const actionsMessage = isChecked ? '2 actions attached' : '1 action attached';
@ -70,14 +70,15 @@ export const HelloWorldExample = ({ uiActionsStartService, openModal }: Props) =
type: ACTION_HELLO_WORLD,
getDisplayName: () => 'Say hello to Waldo',
execute: async () => {
const overlay = openModal(
const overlay = startServices.overlays.openModal(
toMountPoint(
<EuiModalBody>
<EuiText data-test-subj="dynamicHelloWorldActionText">Hello Waldo</EuiText>{' '}
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
Close
</EuiButton>
</EuiModalBody>
</EuiModalBody>,
startServices
)
);
},

View file

@ -51,7 +51,7 @@ export class UiActionsExplorerPlugin implements Plugin<void, void, {}, StartDeps
);
deps.uiActions.addTriggerAction(
USER_TRIGGER,
createEditUserAction(async () => (await startServices)[0].overlays.openModal)
createEditUserAction(async () => (await startServices)[0])
);
deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, viewInMapsAction);
@ -68,10 +68,7 @@ export class UiActionsExplorerPlugin implements Plugin<void, void, {}, StartDeps
async mount(params: AppMountParameters) {
const [coreStart, depsStart] = await core.getStartServices();
const { renderApp } = await import('./app');
return renderApp(
{ uiActionsStartService: depsStart.uiActions, openModal: coreStart.overlays.openModal },
params
);
return renderApp({ uiActionsStartService: depsStart.uiActions, core: coreStart }, params);
},
});

View file

@ -14,9 +14,9 @@
],
"kbn_references": [
"@kbn/core",
"@kbn/kibana-react-plugin",
"@kbn/ui-actions-plugin",
"@kbn/ui-actions-examples-plugin",
"@kbn/developer-examples-plugin",
"@kbn/react-kibana-mount",
]
}

View file

@ -11,11 +11,11 @@
"@kbn/i18n",
"@kbn/content-management-table-list-view-table",
"@kbn/content-management-table-list-view",
"@kbn/kibana-react-plugin",
"@kbn/i18n-react",
"@kbn/shared-ux-file-image",
"@kbn/shared-ux-router",
"@kbn/content-management-table-list-view-common",
"@kbn/kibana-react-plugin",
],
"exclude": [
"target/**/*",

View file

@ -8,9 +8,9 @@
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { ScopedHistory, CoreStart, CoreTheme } from '@kbn/core/public';
import { Observable } from 'rxjs';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { ScopedHistory, CoreStart } from '@kbn/core/public';
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';
@ -24,7 +24,6 @@ import './index.scss';
export const renderApp = async (
element: HTMLElement,
theme$: Observable<CoreTheme>,
coreStart: CoreStart,
history: ScopedHistory
) => {
@ -44,19 +43,19 @@ export const renderApp = async (
);
render(
<RedirectAppLinks
coreStart={{
application: coreStart.application,
}}
>
<KibanaThemeProvider theme$={theme$}>
<KibanaRenderContextProvider i18n={coreStart.i18n} theme={coreStart.theme}>
<RedirectAppLinks
coreStart={{
application: coreStart.application,
}}
>
<KibanaContextProvider services={{ ...coreStart }}>
<SampleDataTabKibanaProvider {...{ coreStart, dataViews, trackUiMetric }}>
<HomeApp directories={directories} solutions={solutions} />
</SampleDataTabKibanaProvider>
</KibanaContextProvider>
</KibanaThemeProvider>
</RedirectAppLinks>,
</RedirectAppLinks>
</KibanaRenderContextProvider>,
element
);
});
@ -64,7 +63,7 @@ export const renderApp = async (
// dispatch synthetic hash change event to update hash history objects
// this is necessary because hash updates triggered by using popState won't trigger this event naturally.
// This must be called before the app is mounted to avoid call this after the redirect to default app logic kicks in
const unlisten = history.listen((location) => {
const unlisten = history.listen((_location) => {
window.dispatchEvent(new HashChangeEvent('hashchange'));
});

View file

@ -116,7 +116,7 @@ export class HomePublicPlugin
i18n.translate('home.pageTitle', { defaultMessage: 'Home' })
);
const { renderApp } = await import('./application');
return await renderApp(params.element, params.theme$, coreStart, params.history);
return await renderApp(params.element, coreStart, params.history);
},
});
urlForwarding.forwardApp('home', 'home');

View file

@ -33,6 +33,7 @@
"@kbn/shared-ux-router",
"@kbn/core-http-common",
"@kbn/shared-ux-link-redirect-app",
"@kbn/react-kibana-context-render",
],
"exclude": [
"target/**/*",

View file

@ -9,8 +9,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n-react';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { NewsfeedApiEndpoint } from '@kbn/newsfeed-plugin/public';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { AppPluginStartDependencies } from './types';
@ -19,7 +19,7 @@ import { KibanaOverviewApp } from './components/app';
export const renderApp = (
core: CoreStart,
deps: AppPluginStartDependencies,
{ appBasePath, element, theme$ }: AppMountParameters
{ appBasePath, element }: AppMountParameters
) => {
const { notifications, http } = core;
const { newsfeed, home, navigation } = deps;
@ -41,16 +41,14 @@ export const renderApp = (
);
ReactDOM.render(
<I18nProvider>
<KibanaThemeProvider theme$={theme$}>
<KibanaContextProvider services={{ ...core, ...deps }}>
<KibanaOverviewApp
basename={appBasePath}
{...{ notifications, http, navigation, newsfeed$, solutions, features$ }}
/>
</KibanaContextProvider>
</KibanaThemeProvider>
</I18nProvider>,
<KibanaRenderContextProvider {...core}>
<KibanaContextProvider services={{ ...core, ...deps }}>
<KibanaOverviewApp
basename={appBasePath}
{...{ notifications, http, navigation, newsfeed$, solutions, features$ }}
/>
</KibanaContextProvider>
</KibanaRenderContextProvider>,
element
);
});

View file

@ -27,6 +27,7 @@
"@kbn/shared-ux-router",
"@kbn/shared-ux-avatar-solution",
"@kbn/shared-ux-utility",
"@kbn/react-kibana-context-render",
],
"exclude": [
"target/**/*",

View file

@ -38,7 +38,7 @@ export const Page: React.FC<PageProps> = ({
if (error) {
return (
<KibanaThemeProvider theme={{ theme$: theme.theme$ }}>
<KibanaThemeProvider theme={theme}>
<EuiPageTemplate>
<RedirectEmptyPrompt docTitle={docTitle} error={error} homeHref={homeHref} />
</EuiPageTemplate>
@ -47,7 +47,7 @@ export const Page: React.FC<PageProps> = ({
}
return (
<KibanaThemeProvider theme={{ theme$: theme.theme$ }}>
<KibanaThemeProvider theme={theme}>
<EuiPageTemplate>
<Spinner showPlainSpinner={Boolean(hasCustomBranding)} />
</EuiPageTemplate>

View file

@ -9,8 +9,7 @@
"browser": true,
"requiredPlugins": [],
"requiredBundles": [
"kibanaUtils",
"kibanaReact"
"kibanaUtils"
]
}
}

View file

@ -11,8 +11,8 @@ import React from 'react';
import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiPopover } from '@elastic/eui';
import { EventEmitter } from 'events';
import ReactDOM from 'react-dom';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { getTheme } from '../services';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { getAnalytics, getI18n, getTheme } from '../services';
let activeSession: ContextMenuSession | null = null;
@ -170,7 +170,7 @@ export function openContextMenu(
};
ReactDOM.render(
<KibanaThemeProvider theme$={getTheme().theme$}>
<KibanaRenderContextProvider analytics={getAnalytics()} i18n={getI18n()} theme={getTheme()}>
<EuiPopover
className="embPanel__optionsMenuPopover"
button={container}
@ -185,7 +185,7 @@ export function openContextMenu(
data-test-subj={props['data-test-subj']}
/>
</EuiPopover>
</KibanaThemeProvider>,
</KibanaRenderContextProvider>,
container
);

View file

@ -14,7 +14,7 @@ import {
visualizeGeoFieldTrigger,
} from '@kbn/ui-actions-browser/src/triggers';
import { UiActionsService } from './service';
import { setTheme } from './services';
import { setAnalytics, setI18n, setTheme } from './services';
export type UiActionsPublicSetup = Pick<
UiActionsService,
@ -47,15 +47,17 @@ export class UiActionsPlugin
constructor(_initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup): UiActionsPublicSetup {
setTheme(core.theme);
public setup(_core: CoreSetup): UiActionsPublicSetup {
this.service.registerTrigger(rowClickTrigger);
this.service.registerTrigger(visualizeFieldTrigger);
this.service.registerTrigger(visualizeGeoFieldTrigger);
return this.service;
}
public start(_core: CoreStart): UiActionsPublicStart {
public start(core: CoreStart): UiActionsPublicStart {
setAnalytics(core.analytics);
setI18n(core.i18n);
setTheme(core.theme);
return this.service;
}

View file

@ -10,8 +10,8 @@ import { UiActionsService } from './ui_actions_service';
import { ActionDefinition, ActionInternal } from '../actions';
import { createHelloWorldAction } from '../tests/test_samples';
import { TriggerRegistry, ActionRegistry } from '../types';
import { coreMock } from '@kbn/core/public/mocks';
import type { Trigger } from '@kbn/ui-actions-browser/src/triggers';
import { OverlayStart } from '@kbn/core/public';
const FOO_TRIGGER = 'FOO_TRIGGER';
const BAR_TRIGGER = 'BAR_TRIGGER';
@ -159,10 +159,12 @@ describe('UiActionsService', () => {
});
describe('.getTriggerCompatibleActions()', () => {
const coreStart = coreMock.createStart();
test('can register and get actions', async () => {
const actions: ActionRegistry = new Map();
const service = new UiActionsService({ actions });
const helloWorldAction = createHelloWorldAction({} as unknown as OverlayStart);
const helloWorldAction = createHelloWorldAction(coreStart);
const length = actions.size;
service.registerAction(helloWorldAction);
@ -173,7 +175,7 @@ describe('UiActionsService', () => {
test('getTriggerCompatibleActions returns attached actions', async () => {
const service = new UiActionsService();
const helloWorldAction = createHelloWorldAction({} as unknown as OverlayStart);
const helloWorldAction = createHelloWorldAction(coreStart);
service.registerAction(helloWorldAction);

View file

@ -6,7 +6,9 @@
* Side Public License, v 1.
*/
import { ThemeServiceSetup } from '@kbn/core/public';
import { AnalyticsServiceStart, I18nStart, ThemeServiceSetup } from '@kbn/core/public';
import { createGetterSetter } from '@kbn/kibana-utils-plugin/public';
export const [getAnalytics, setAnalytics] = createGetterSetter<AnalyticsServiceStart>('Analytics');
export const [getI18n, setI18n] = createGetterSetter<I18nStart>('I18n');
export const [getTheme, setTheme] = createGetterSetter<ThemeServiceSetup>('Theme');

View file

@ -9,9 +9,10 @@
import { uiActionsPluginMock } from '../mocks';
import { createHelloWorldAction } from './test_samples';
import { ActionDefinition } from '../actions';
import { coreMock } from '@kbn/core/public/mocks';
import type { Trigger } from '@kbn/ui-actions-browser';
import { OverlayStart } from '@kbn/core/public';
const coreStart = coreMock.createStart();
let action: ActionDefinition<{ name: string }>;
let uiActions: ReturnType<typeof uiActionsPluginMock.createPlugin>;
beforeEach(() => {
@ -32,14 +33,14 @@ beforeEach(() => {
test('can register action', async () => {
const { setup } = uiActions;
const helloWorldAction = createHelloWorldAction({} as unknown as OverlayStart);
const helloWorldAction = createHelloWorldAction(coreStart);
setup.registerAction(helloWorldAction);
});
test('getTriggerCompatibleActions returns attached actions', async () => {
const { setup, doStart } = uiActions;
const helloWorldAction = createHelloWorldAction({} as unknown as OverlayStart);
const helloWorldAction = createHelloWorldAction(coreStart);
setup.registerAction(helloWorldAction);

View file

@ -9,7 +9,7 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiFlyoutBody } from '@elastic/eui';
import { CoreStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { ActionDefinition } from '../../actions';
const MenuItem: React.FC = () => {
@ -25,7 +25,10 @@ const MenuItem: React.FC = () => {
export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD';
export function createHelloWorldAction(overlays: CoreStart['overlays']): ActionDefinition {
export function createHelloWorldAction(
coreStart: Pick<CoreStart, 'overlays' | 'analytics' | 'i18n' | 'theme'>
): ActionDefinition {
const { overlays, ...startServices } = coreStart;
return {
id: ACTION_HELLO_WORLD,
type: ACTION_HELLO_WORLD,
@ -33,7 +36,10 @@ export function createHelloWorldAction(overlays: CoreStart['overlays']): ActionD
MenuItem,
execute: async () => {
overlays.openFlyout(
toMountPoint(<EuiFlyoutBody>Hello World, I am a hello world action!</EuiFlyoutBody>),
toMountPoint(
<EuiFlyoutBody>Hello World, I am a hello world action!</EuiFlyoutBody>,
startServices
),
{
'data-test-subj': 'helloWorldAction',
ownFocus: true,

View file

@ -7,13 +7,14 @@
"kbn_references": [
"@kbn/core",
"@kbn/kibana-utils-plugin",
"@kbn/kibana-react-plugin",
"@kbn/data-views-plugin",
"@kbn/utility-types",
"@kbn/i18n",
"@kbn/es-query",
"@kbn/ui-actions-browser",
"@kbn/expressions-plugin",
"@kbn/react-kibana-context-render",
"@kbn/react-kibana-mount",
],
"exclude": [
"target/**/*",

View file

@ -13,8 +13,6 @@
"uiActions",
"embeddable"
],
"requiredBundles": [
"kibanaReact"
]
"requiredBundles": []
}
}

View file

@ -12,7 +12,7 @@ import React from 'react';
import { IEmbeddable } from '@kbn/embeddable-plugin/public';
import { createAction } from '@kbn/ui-actions-plugin/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
export const SAMPLE_PANEL_ACTION = 'samplePanelAction';
@ -29,7 +29,9 @@ export function createSamplePanelAction(getStartServices: CoreSetup['getStartSer
if (!embeddable) {
return;
}
const openFlyout = (await getStartServices())[0].overlays.openFlyout;
const coreStart = (await getStartServices())[0];
const { overlays, ...startServices } = coreStart;
const openFlyout = overlays.openFlyout;
openFlyout(
toMountPoint(
<React.Fragment>
@ -41,7 +43,8 @@ export function createSamplePanelAction(getStartServices: CoreSetup['getStartSer
<EuiFlyoutBody>
<h3 data-test-subj="samplePanelActionBody">This is a sample action</h3>
</EuiFlyoutBody>
</React.Fragment>
</React.Fragment>,
startServices
),
{
'data-test-subj': 'samplePanelActionFlyout',

View file

@ -16,6 +16,6 @@
"@kbn/core",
"@kbn/ui-actions-plugin",
"@kbn/embeddable-plugin",
"@kbn/kibana-react-plugin",
"@kbn/react-kibana-mount",
]
}

View file

@ -22,8 +22,7 @@
"requiredBundles": [
"dashboardEnhanced",
"embeddable",
"kibanaUtils",
"kibanaReact"
"kibanaUtils"
]
}
}

View file

@ -6,7 +6,7 @@
*/
import { createElement as h } from 'react';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { Plugin, CoreSetup, CoreStart } from '@kbn/core/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public';
import {
@ -93,7 +93,8 @@ export class UiActionsEnhancedExamplesPlugin
dynamicActionManager: self.managerWithoutEmbeddableSingleButton,
triggers: [SAMPLE_APP2_CLICK_TRIGGER],
placeContext: {},
})
}),
coreStart
),
{
ownFocus: true,
@ -118,7 +119,8 @@ export class UiActionsEnhancedExamplesPlugin
dynamicActionManager: self.managerWithoutEmbeddableSingleButton,
triggers: [SAMPLE_APP2_CLICK_TRIGGER],
placeContext: { sampleApp2ClickContext },
})
}),
coreStart
),
{
ownFocus: true,
@ -150,7 +152,7 @@ export class UiActionsEnhancedExamplesPlugin
});
}
public start(core: CoreStart, plugins: StartDependencies): UiActionsEnhancedExamplesStart {
public start(_core: CoreStart, plugins: StartDependencies): UiActionsEnhancedExamplesStart {
const managerWithoutEmbeddable = new UiActionsEnhancedDynamicActionManager({
storage: new UiActionsEnhancedMemoryActionStorage(),
isCompatible: async () => true,

View file

@ -16,7 +16,6 @@
"kbn_references": [
"@kbn/core",
"@kbn/kibana-utils-plugin",
"@kbn/kibana-react-plugin",
"@kbn/share-plugin",
"@kbn/discover-plugin",
"@kbn/dashboard-plugin",
@ -30,5 +29,6 @@
"@kbn/unified-search-plugin",
"@kbn/utility-types",
"@kbn/presentation-publishing",
"@kbn/react-kibana-mount",
]
}

View file

@ -17,8 +17,6 @@
"optionalPlugins": [
"screenshotMode"
],
"requiredBundles": [
"kibanaReact"
]
"requiredBundles": []
}
}

View file

@ -7,20 +7,20 @@
import React from 'react';
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { Banner } from './components';
import { getBannerInfo } from './get_banner_info';
import { BannerPluginStartDependencies } from './types';
export class BannersPlugin implements Plugin<{}, {}, {}, BannerPluginStartDependencies> {
constructor(context: PluginInitializerContext) {}
constructor(_context: PluginInitializerContext) {}
setup({}: CoreSetup<{}, {}>) {
return {};
}
start(
{ chrome, uiSettings, http }: CoreStart,
{ chrome, http, ...startServices }: CoreStart,
{ screenshotMode }: BannerPluginStartDependencies
) {
if (!(screenshotMode?.isScreenshotMode() ?? false)) {
@ -28,7 +28,7 @@ export class BannersPlugin implements Plugin<{}, {}, {}, BannerPluginStartDepend
({ allowed, banner }) => {
if (allowed && banner.placement === 'top') {
chrome.setHeaderBanner({
content: toMountPoint(<Banner bannerConfig={banner} />),
content: toMountPoint(<Banner bannerConfig={banner} />, startServices),
});
}
},

View file

@ -6,12 +6,12 @@
"include": ["public/**/*", "server/**/*", "common/**/*", "../../../typings/**/*"],
"kbn_references": [
"@kbn/core",
"@kbn/kibana-react-plugin",
"@kbn/screenshot-mode-plugin",
"@kbn/licensing-plugin",
"@kbn/config-schema",
"@kbn/i18n",
"@kbn/shared-ux-markdown",
"@kbn/react-kibana-mount",
],
"exclude": [
"target/**/*",

View file

@ -19,8 +19,6 @@
"usageCollection",
"security"
],
"requiredBundles": [
"kibanaReact"
]
"requiredBundles": []
}
}

View file

@ -7,14 +7,12 @@
import React from 'react';
import { EuiDelayRender, EuiLoadingSpinner } from '@elastic/eui';
import { NotificationsStart, OverlayStart, ThemeServiceStart, OverlayRef } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { OverlayRef } from '@kbn/core/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { ITagAssignmentService, ITagsCache } from '../../services';
import { StartServices } from '../../types';
export interface GetAssignFlyoutOpenerOptions {
overlays: OverlayStart;
notifications: NotificationsStart;
theme: ThemeServiceStart;
export interface GetAssignFlyoutOpenerOptions extends StartServices {
tagCache: ITagsCache;
assignmentService: ITagAssignmentService;
assignableTypes: string[];
@ -43,10 +41,10 @@ export const getAssignFlyoutOpener =
({
overlays,
notifications,
theme,
tagCache,
assignmentService,
assignableTypes,
...startServices
}: GetAssignFlyoutOpenerOptions): AssignFlyoutOpener =>
async ({ tagIds }) => {
const flyout = overlays.openFlyout(
@ -61,7 +59,7 @@ export const getAssignFlyoutOpener =
onClose={() => flyout.close()}
/>
</React.Suspense>,
{ theme$: theme.theme$ }
startServices
),
{ size: 'm', maxWidth: 600 }
);

View file

@ -7,20 +7,13 @@
import React from 'react';
import { EuiDelayRender, EuiLoadingSpinner } from '@elastic/eui';
import type {
OverlayStart,
OverlayRef,
ThemeServiceStart,
NotificationsStart,
} from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import type { OverlayRef } from '@kbn/core/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { Tag, TagAttributes } from '../../../common/types';
import { ITagInternalClient } from '../../services';
import { StartServices } from '../../types';
interface GetModalOpenerOptions {
overlays: OverlayStart;
notifications: NotificationsStart;
theme: ThemeServiceStart;
interface GetModalOpenerOptions extends StartServices {
tagClient: ITagInternalClient;
}
@ -46,7 +39,12 @@ const LazyEditTagModal = React.lazy(() =>
);
export const getCreateModalOpener =
({ overlays, theme, tagClient, notifications }: GetModalOpenerOptions): CreateModalOpener =>
({
overlays,
tagClient,
notifications,
...startServices
}: GetModalOpenerOptions): CreateModalOpener =>
async ({ onCreate, defaultValues }: OpenCreateModalOptions) => {
const modal = overlays.openModal(
toMountPoint(
@ -64,7 +62,7 @@ export const getCreateModalOpener =
notifications={notifications}
/>
</React.Suspense>,
{ theme$: theme.theme$ }
startServices
)
);
return modal;
@ -76,7 +74,7 @@ interface OpenEditModalOptions {
}
export const getEditModalOpener =
({ overlays, theme, tagClient, notifications }: GetModalOpenerOptions) =>
({ overlays, tagClient, notifications, ...startServices }: GetModalOpenerOptions) =>
async ({ tagId, onUpdate }: OpenEditModalOptions) => {
const tag = await tagClient.get(tagId);
@ -96,7 +94,7 @@ export const getEditModalOpener =
notifications={notifications}
/>
</React.Suspense>,
{ theme$: theme.theme$ }
startServices
)
);

View file

@ -5,20 +5,16 @@
* 2.0.
*/
import { Observable, from } from 'rxjs';
import { takeUntil } from 'rxjs';
import { i18n } from '@kbn/i18n';
import { NotificationsStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { Observable, from, takeUntil } from 'rxjs';
import { TagWithRelations } from '../../../common';
import { ITagsCache } from '../../services/tags';
import { getAssignFlyoutOpener } from '../../components/assign_flyout';
import { ITagAssignmentService } from '../../services/assignments';
import { ITagsCache } from '../../services/tags';
import { StartServices } from '../../types';
import { TagAction } from './types';
interface GetAssignActionOptions {
overlays: OverlayStart;
notifications: NotificationsStart;
theme: ThemeServiceStart;
interface GetAssignActionOptions extends StartServices {
tagCache: ITagsCache;
assignmentService: ITagAssignmentService;
assignableTypes: string[];
@ -27,19 +23,15 @@ interface GetAssignActionOptions {
}
export const getAssignAction = ({
notifications,
overlays,
theme,
assignableTypes,
assignmentService,
tagCache,
fetchTags,
canceled$,
...startServices
}: GetAssignActionOptions): TagAction => {
const openFlyout = getAssignFlyoutOpener({
overlays,
notifications,
theme,
...startServices,
tagCache,
assignmentService,
assignableTypes,

View file

@ -6,28 +6,26 @@
*/
import { i18n } from '@kbn/i18n';
import { NotificationsStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { TagWithRelations } from '../../../common';
import { ITagInternalClient } from '../../services/tags';
import { getEditModalOpener } from '../../components/edition_modal';
import { ITagInternalClient } from '../../services/tags';
import { StartServices } from '../../types';
import { TagAction } from './types';
interface GetEditActionOptions {
overlays: OverlayStart;
theme: ThemeServiceStart;
notifications: NotificationsStart;
interface GetEditActionOptions extends StartServices {
tagClient: ITagInternalClient;
fetchTags: () => Promise<void>;
}
export const getEditAction = ({
notifications,
theme,
overlays,
tagClient,
fetchTags,
...startServices
}: GetEditActionOptions): TagAction => {
const editModalOpener = getEditModalOpener({ overlays, theme, tagClient, notifications });
const editModalOpener = getEditModalOpener({
...startServices,
tagClient,
});
return {
id: 'edit',
name: ({ name }) =>
@ -46,6 +44,7 @@ export const getEditAction = ({
icon: 'pencil',
available: (tag) => !tag.managed,
onClick: (tag: TagWithRelations) => {
const { notifications } = startServices;
editModalOpener({
tagId: tag.id,
onUpdate: (updatedTag) => {

View file

@ -36,7 +36,7 @@ describe('getTableActions', () => {
{ assignableTypes = ['foo', 'bar'] }: { assignableTypes?: string[] } = {}
) =>
getTableActions({
core,
startServices: core,
tagClient,
tagCache,
assignmentService,

View file

@ -6,9 +6,9 @@
*/
import { Observable } from 'rxjs';
import { CoreStart } from '@kbn/core/public';
import { TagsCapabilities } from '../../../common';
import { ITagInternalClient, ITagAssignmentService, ITagsCache } from '../../services';
import { StartServices } from '../../types';
import { TagAction } from './types';
import { getDeleteAction } from './delete';
import { getEditAction } from './edit';
@ -17,7 +17,7 @@ import { getAssignAction } from './assign';
export type { TagAction } from './types';
interface GetActionsOptions {
core: CoreStart;
startServices: StartServices;
capabilities: TagsCapabilities;
tagClient: ITagInternalClient;
tagCache: ITagsCache;
@ -29,7 +29,7 @@ interface GetActionsOptions {
}
export const getTableActions = ({
core: { notifications, overlays, theme },
startServices,
capabilities,
tagClient,
tagCache,
@ -41,26 +41,24 @@ export const getTableActions = ({
const actions: TagAction[] = [];
if (capabilities.edit) {
actions.push(getEditAction({ notifications, overlays, theme, tagClient, fetchTags }));
actions.push(getEditAction({ ...startServices, tagClient, fetchTags }));
}
if (capabilities.assign && assignableTypes.length > 0) {
actions.push(
getAssignAction({
...startServices,
tagCache,
assignmentService,
assignableTypes,
fetchTags,
notifications,
overlays,
theme,
canceled$,
})
);
}
if (capabilities.delete) {
actions.push(getDeleteAction({ overlays, notifications, tagClient, fetchTags }));
actions.push(getDeleteAction({ ...startServices, tagClient, fetchTags }));
}
return actions;

View file

@ -7,16 +7,13 @@
import { from } from 'rxjs';
import { takeUntil } from 'rxjs';
import { OverlayStart, NotificationsStart, ThemeServiceStart } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { ITagsCache, ITagAssignmentService } from '../../services';
import { StartServices } from '../../types';
import { TagBulkAction } from '../types';
import { getAssignFlyoutOpener } from '../../components/assign_flyout';
interface GetBulkAssignActionOptions {
overlays: OverlayStart;
notifications: NotificationsStart;
theme: ThemeServiceStart;
interface GetBulkAssignActionOptions extends StartServices {
tagCache: ITagsCache;
assignmentService: ITagAssignmentService;
assignableTypes: string[];
@ -24,17 +21,13 @@ interface GetBulkAssignActionOptions {
}
export const getBulkAssignAction = ({
overlays,
notifications,
theme,
tagCache,
assignmentService,
assignableTypes,
...startServices
}: GetBulkAssignActionOptions): TagBulkAction => {
const openFlyout = getAssignFlyoutOpener({
overlays,
notifications,
theme,
...startServices,
tagCache,
assignmentService,
assignableTypes,

View file

@ -37,7 +37,7 @@ describe('getBulkActions', () => {
{ assignableTypes = ['foo', 'bar'] }: { assignableTypes?: string[] } = {}
) =>
getBulkActions({
core,
startServices: core,
tagClient,
tagCache,
assignmentService,

View file

@ -5,16 +5,16 @@
* 2.0.
*/
import { CoreStart } from '@kbn/core/public';
import { TagsCapabilities } from '../../../common';
import { ITagInternalClient, ITagAssignmentService, ITagsCache } from '../../services';
import { StartServices } from '../../types';
import { TagBulkAction } from '../types';
import { getBulkDeleteAction } from './bulk_delete';
import { getBulkAssignAction } from './bulk_assign';
import { getClearSelectionAction } from './clear_selection';
interface GetBulkActionOptions {
core: CoreStart;
startServices: StartServices;
capabilities: TagsCapabilities;
tagClient: ITagInternalClient;
tagCache: ITagsCache;
@ -25,7 +25,7 @@ interface GetBulkActionOptions {
}
export const getBulkActions = ({
core: { notifications, overlays, theme },
startServices,
capabilities,
tagClient,
tagCache,
@ -39,9 +39,7 @@ export const getBulkActions = ({
if (capabilities.assign && assignableTypes.length > 0) {
actions.push(
getBulkAssignAction({
notifications,
overlays,
theme,
...startServices,
tagCache,
assignmentService,
assignableTypes,
@ -50,7 +48,7 @@ export const getBulkActions = ({
);
}
if (capabilities.delete) {
actions.push(getBulkDeleteAction({ notifications, overlays, tagClient, setLoading }));
actions.push(getBulkDeleteAction({ ...startServices, tagClient, setLoading }));
}
// only add clear selection if user has permission to perform any other action

View file

@ -7,9 +7,8 @@
import React, { FC } from 'react';
import ReactDOM from 'react-dom';
import { I18nProvider } from '@kbn/i18n-react';
import { CoreSetup, ApplicationStart } from '@kbn/core/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { ManagementAppMountParams } from '@kbn/management-plugin/public';
import { getTagsCapabilities } from '../../common';
import { SavedObjectTaggingPluginStart } from '../types';
@ -45,27 +44,25 @@ export const mountSection = async ({
title,
}: MountSectionParams) => {
const [coreStart] = await core.getStartServices();
const { element, setBreadcrumbs, theme$ } = mountParams;
const { element, setBreadcrumbs } = mountParams;
const capabilities = getTagsCapabilities(coreStart.application.capabilities);
const assignableTypes = await assignmentService.getAssignableTypes();
coreStart.chrome.docTitle.change(title);
ReactDOM.render(
<I18nProvider>
<KibanaThemeProvider theme$={theme$}>
<RedirectToHomeIfUnauthorized applications={coreStart.application}>
<TagManagementPage
setBreadcrumbs={setBreadcrumbs}
core={coreStart}
tagClient={tagClient}
tagCache={tagCache}
assignmentService={assignmentService}
capabilities={capabilities}
assignableTypes={assignableTypes}
/>
</RedirectToHomeIfUnauthorized>
</KibanaThemeProvider>
</I18nProvider>,
<KibanaRenderContextProvider {...coreStart}>
<RedirectToHomeIfUnauthorized applications={coreStart.application}>
<TagManagementPage
setBreadcrumbs={setBreadcrumbs}
core={coreStart}
tagClient={tagClient}
tagCache={tagCache}
assignmentService={assignmentService}
capabilities={capabilities}
assignableTypes={assignableTypes}
/>
</RedirectToHomeIfUnauthorized>
</KibanaRenderContextProvider>,
element
);

View file

@ -40,7 +40,7 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
capabilities,
assignableTypes,
}) => {
const { overlays, notifications, application, http, theme } = core;
const { application, http, ...startServices } = core;
const [loading, setLoading] = useState<boolean>(false);
const [allTags, setAllTags] = useState<TagWithRelations[]>([]);
const [selectedTags, setSelectedTags] = useState<TagWithRelations[]>([]);
@ -75,13 +75,13 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
});
const createModalOpener = useMemo(
() => getCreateModalOpener({ overlays, theme, tagClient, notifications }),
[overlays, theme, tagClient, notifications]
() => getCreateModalOpener({ ...startServices, tagClient }),
[startServices, tagClient]
);
const tableActions = useMemo(() => {
return getTableActions({
core,
startServices,
capabilities,
tagClient,
tagCache,
@ -92,7 +92,7 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
canceled$: unmount$,
});
}, [
core,
startServices,
capabilities,
tagClient,
tagCache,
@ -105,7 +105,7 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
const bulkActions = useMemo(() => {
return getBulkActions({
core,
startServices,
capabilities,
tagClient,
tagCache,
@ -114,7 +114,7 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
assignableTypes,
clearSelection: () => setSelectedTags([]),
});
}, [core, capabilities, tagClient, tagCache, assignmentService, assignableTypes]);
}, [startServices, capabilities, tagClient, tagCache, assignmentService, assignableTypes]);
useEffect(() => {
setBreadcrumbs([
@ -126,6 +126,8 @@ export const TagManagementPage: FC<TagManagementPageParams> = ({
]);
}, [setBreadcrumbs]);
const { notifications } = startServices;
const openCreateModal = useCallback(() => {
createModalOpener({
onCreate: (createdTag) => {

View file

@ -67,7 +67,7 @@ export class SavedObjectTaggingPlugin
return {};
}
public start({ http, application, overlays, theme, analytics, notifications }: CoreStart) {
public start({ http, application, analytics, ...startServices }: CoreStart) {
this.tagCache = new TagsCache({
refreshHandler: () => this.tagClient!.getAll({ asSystemRequest: true }),
refreshInterval: this.config.cacheRefreshInterval,
@ -87,12 +87,11 @@ export class SavedObjectTaggingPlugin
client: this.tagClient,
cache: this.tagCache,
ui: getUiApi({
...startServices,
analytics,
cache: this.tagCache,
client: this.tagClient,
capabilities: getTagsCapabilities(application.capabilities),
overlays,
theme,
notifications,
}),
};
}

View file

@ -5,6 +5,12 @@
* 2.0.
*/
import { CoreStart } from '@kbn/core-lifecycle-browser';
import type { SavedObjectsTaggingApi } from '@kbn/saved-objects-tagging-oss-plugin/public';
export type SavedObjectTaggingPluginStart = SavedObjectsTaggingApi;
export type StartServices = Pick<
CoreStart,
'overlays' | 'notifications' | 'analytics' | 'i18n' | 'theme'
>;

View file

@ -5,7 +5,6 @@
* 2.0.
*/
import { NotificationsStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { SavedObjectsTaggingApiUiComponent } from '@kbn/saved-objects-tagging-oss-plugin/public';
import { TagsCapabilities } from '../../common';
import { ITagInternalClient, ITagsCache } from '../services';
@ -15,25 +14,21 @@ import {
getConnectedSavedObjectModalTagSelectorComponent,
} from '../components/connected';
import { getCreateModalOpener } from '../components/edition_modal';
import { StartServices } from '../types';
export interface GetComponentsOptions {
export interface GetComponentsOptions extends StartServices {
capabilities: TagsCapabilities;
cache: ITagsCache;
overlays: OverlayStart;
theme: ThemeServiceStart;
tagClient: ITagInternalClient;
notifications: NotificationsStart;
}
export const getComponents = ({
capabilities,
cache,
overlays,
theme,
tagClient,
notifications,
...startServices
}: GetComponentsOptions): SavedObjectsTaggingApiUiComponent => {
const openCreateModal = getCreateModalOpener({ overlays, theme, tagClient, notifications });
const openCreateModal = getCreateModalOpener({ ...startServices, tagClient });
return {
TagList: getConnectedTagListComponent({ cache }),
TagSelector: getConnectedTagSelectorComponent({ cache, capabilities, openCreateModal }),

View file

@ -5,10 +5,10 @@
* 2.0.
*/
import type { NotificationsStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { SavedObjectsTaggingApiUi } from '@kbn/saved-objects-tagging-oss-plugin/public';
import { TagsCapabilities } from '../../common';
import { ITagsCache, ITagInternalClient } from '../services';
import { StartServices } from '../types';
import {
getTagIdsFromReferences,
updateTagsReferences,
@ -23,30 +23,23 @@ import { buildConvertNameToReference } from './convert_name_to_reference';
import { buildGetTagList } from './get_tag_list';
import { hasTagDecoration } from './has_tag_decoration';
interface GetUiApiOptions {
overlays: OverlayStart;
theme: ThemeServiceStart;
interface GetUiApiOptions extends StartServices {
capabilities: TagsCapabilities;
cache: ITagsCache;
client: ITagInternalClient;
notifications: NotificationsStart;
}
export const getUiApi = ({
cache,
capabilities,
client,
overlays,
theme,
notifications,
...startServices
}: GetUiApiOptions): SavedObjectsTaggingApiUi => {
const components = getComponents({
...startServices,
cache,
capabilities,
overlays,
theme,
tagClient: client,
notifications,
});
const getTagList = buildGetTagList(cache);

View file

@ -13,7 +13,6 @@
"@kbn/usage-collection-plugin",
"@kbn/management-plugin",
"@kbn/saved-objects-tagging-oss-plugin",
"@kbn/kibana-react-plugin",
"@kbn/usage-collection-plugin",
"@kbn/features-plugin",
"@kbn/security-plugin",
@ -24,6 +23,9 @@
"@kbn/ebt-tools",
"@kbn/core-notifications-browser",
"@kbn/ui-theme",
"@kbn/react-kibana-context-render",
"@kbn/react-kibana-mount",
"@kbn/core-lifecycle-browser",
],
"exclude": [
"target/**/*",

View file

@ -16,8 +16,6 @@
"cloud"
],
"optionalPlugins": [],
"requiredBundles": [
"kibanaReact",
]
"requiredBundles": []
}
}

View file

@ -7,8 +7,7 @@
import { InternalChromeStart } from '@kbn/core-chrome-browser-internal';
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { I18nProvider } from '@kbn/i18n-react';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { ProjectSwitcher, ProjectSwitcherKibanaProvider } from '@kbn/serverless-project-switcher';
import { ProjectType } from '@kbn/serverless-types';
import React from 'react';
@ -120,13 +119,11 @@ export class ServerlessPlugin
currentProjectType: ProjectType
) {
ReactDOM.render(
<I18nProvider>
<KibanaThemeProvider theme$={coreStart.theme.theme$}>
<ProjectSwitcherKibanaProvider {...{ coreStart, projectChangeAPIUrl }}>
<ProjectSwitcher {...{ currentProjectType }} />
</ProjectSwitcherKibanaProvider>
</KibanaThemeProvider>
</I18nProvider>,
<KibanaRenderContextProvider i18n={coreStart.i18n} theme={coreStart.theme}>
<ProjectSwitcherKibanaProvider {...{ coreStart, projectChangeAPIUrl }}>
<ProjectSwitcher {...{ currentProjectType }} />
</ProjectSwitcherKibanaProvider>
</KibanaRenderContextProvider>,
targetDomElement
);

View file

@ -16,17 +16,16 @@
"kbn_references": [
"@kbn/config-schema",
"@kbn/core",
"@kbn/kibana-react-plugin",
"@kbn/serverless-project-switcher",
"@kbn/serverless-types",
"@kbn/utils",
"@kbn/core-chrome-browser",
"@kbn/core-chrome-browser-internal",
"@kbn/i18n-react",
"@kbn/cloud-plugin",
"@kbn/serverless-common-settings",
"@kbn/shared-ux-chrome-navigation",
"@kbn/i18n",
"@kbn/management-cards-navigation",
"@kbn/react-kibana-context-render",
]
}