[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": [ "requiredPlugins": [
"uiActions" "uiActions"
], ],
"requiredBundles": [ "requiredBundles": []
"kibanaReact"
]
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,9 +8,9 @@
import React from 'react'; import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom'; import { render, unmountComponentAtNode } from 'react-dom';
import { ScopedHistory, CoreStart, CoreTheme } from '@kbn/core/public'; import { ScopedHistory, CoreStart } from '@kbn/core/public';
import { Observable } from 'rxjs'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
@ -24,7 +24,6 @@ import './index.scss';
export const renderApp = async ( export const renderApp = async (
element: HTMLElement, element: HTMLElement,
theme$: Observable<CoreTheme>,
coreStart: CoreStart, coreStart: CoreStart,
history: ScopedHistory history: ScopedHistory
) => { ) => {
@ -44,19 +43,19 @@ export const renderApp = async (
); );
render( render(
<RedirectAppLinks <KibanaRenderContextProvider i18n={coreStart.i18n} theme={coreStart.theme}>
coreStart={{ <RedirectAppLinks
application: coreStart.application, coreStart={{
}} application: coreStart.application,
> }}
<KibanaThemeProvider theme$={theme$}> >
<KibanaContextProvider services={{ ...coreStart }}> <KibanaContextProvider services={{ ...coreStart }}>
<SampleDataTabKibanaProvider {...{ coreStart, dataViews, trackUiMetric }}> <SampleDataTabKibanaProvider {...{ coreStart, dataViews, trackUiMetric }}>
<HomeApp directories={directories} solutions={solutions} /> <HomeApp directories={directories} solutions={solutions} />
</SampleDataTabKibanaProvider> </SampleDataTabKibanaProvider>
</KibanaContextProvider> </KibanaContextProvider>
</KibanaThemeProvider> </RedirectAppLinks>
</RedirectAppLinks>, </KibanaRenderContextProvider>,
element element
); );
}); });
@ -64,7 +63,7 @@ export const renderApp = async (
// dispatch synthetic hash change event to update hash history objects // 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 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 // 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')); window.dispatchEvent(new HashChangeEvent('hashchange'));
}); });

View file

@ -116,7 +116,7 @@ export class HomePublicPlugin
i18n.translate('home.pageTitle', { defaultMessage: 'Home' }) i18n.translate('home.pageTitle', { defaultMessage: 'Home' })
); );
const { renderApp } = await import('./application'); 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'); urlForwarding.forwardApp('home', 'home');

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,7 +6,9 @@
* Side Public License, v 1. * 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'; 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'); export const [getTheme, setTheme] = createGetterSetter<ThemeServiceSetup>('Theme');

View file

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

View file

@ -9,7 +9,7 @@
import React from 'react'; import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiFlyoutBody } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiFlyoutBody } from '@elastic/eui';
import { CoreStart } from '@kbn/core/public'; 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'; import { ActionDefinition } from '../../actions';
const MenuItem: React.FC = () => { const MenuItem: React.FC = () => {
@ -25,7 +25,10 @@ const MenuItem: React.FC = () => {
export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD'; 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 { return {
id: ACTION_HELLO_WORLD, id: ACTION_HELLO_WORLD,
type: ACTION_HELLO_WORLD, type: ACTION_HELLO_WORLD,
@ -33,7 +36,10 @@ export function createHelloWorldAction(overlays: CoreStart['overlays']): ActionD
MenuItem, MenuItem,
execute: async () => { execute: async () => {
overlays.openFlyout( 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', 'data-test-subj': 'helloWorldAction',
ownFocus: true, ownFocus: true,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,16 +5,16 @@
* 2.0. * 2.0.
*/ */
import { CoreStart } from '@kbn/core/public';
import { TagsCapabilities } from '../../../common'; import { TagsCapabilities } from '../../../common';
import { ITagInternalClient, ITagAssignmentService, ITagsCache } from '../../services'; import { ITagInternalClient, ITagAssignmentService, ITagsCache } from '../../services';
import { StartServices } from '../../types';
import { TagBulkAction } from '../types'; import { TagBulkAction } from '../types';
import { getBulkDeleteAction } from './bulk_delete'; import { getBulkDeleteAction } from './bulk_delete';
import { getBulkAssignAction } from './bulk_assign'; import { getBulkAssignAction } from './bulk_assign';
import { getClearSelectionAction } from './clear_selection'; import { getClearSelectionAction } from './clear_selection';
interface GetBulkActionOptions { interface GetBulkActionOptions {
core: CoreStart; startServices: StartServices;
capabilities: TagsCapabilities; capabilities: TagsCapabilities;
tagClient: ITagInternalClient; tagClient: ITagInternalClient;
tagCache: ITagsCache; tagCache: ITagsCache;
@ -25,7 +25,7 @@ interface GetBulkActionOptions {
} }
export const getBulkActions = ({ export const getBulkActions = ({
core: { notifications, overlays, theme }, startServices,
capabilities, capabilities,
tagClient, tagClient,
tagCache, tagCache,
@ -39,9 +39,7 @@ export const getBulkActions = ({
if (capabilities.assign && assignableTypes.length > 0) { if (capabilities.assign && assignableTypes.length > 0) {
actions.push( actions.push(
getBulkAssignAction({ getBulkAssignAction({
notifications, ...startServices,
overlays,
theme,
tagCache, tagCache,
assignmentService, assignmentService,
assignableTypes, assignableTypes,
@ -50,7 +48,7 @@ export const getBulkActions = ({
); );
} }
if (capabilities.delete) { 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 // 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 React, { FC } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { I18nProvider } from '@kbn/i18n-react';
import { CoreSetup, ApplicationStart } from '@kbn/core/public'; 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 { ManagementAppMountParams } from '@kbn/management-plugin/public';
import { getTagsCapabilities } from '../../common'; import { getTagsCapabilities } from '../../common';
import { SavedObjectTaggingPluginStart } from '../types'; import { SavedObjectTaggingPluginStart } from '../types';
@ -45,27 +44,25 @@ export const mountSection = async ({
title, title,
}: MountSectionParams) => { }: MountSectionParams) => {
const [coreStart] = await core.getStartServices(); const [coreStart] = await core.getStartServices();
const { element, setBreadcrumbs, theme$ } = mountParams; const { element, setBreadcrumbs } = mountParams;
const capabilities = getTagsCapabilities(coreStart.application.capabilities); const capabilities = getTagsCapabilities(coreStart.application.capabilities);
const assignableTypes = await assignmentService.getAssignableTypes(); const assignableTypes = await assignmentService.getAssignableTypes();
coreStart.chrome.docTitle.change(title); coreStart.chrome.docTitle.change(title);
ReactDOM.render( ReactDOM.render(
<I18nProvider> <KibanaRenderContextProvider {...coreStart}>
<KibanaThemeProvider theme$={theme$}> <RedirectToHomeIfUnauthorized applications={coreStart.application}>
<RedirectToHomeIfUnauthorized applications={coreStart.application}> <TagManagementPage
<TagManagementPage setBreadcrumbs={setBreadcrumbs}
setBreadcrumbs={setBreadcrumbs} core={coreStart}
core={coreStart} tagClient={tagClient}
tagClient={tagClient} tagCache={tagCache}
tagCache={tagCache} assignmentService={assignmentService}
assignmentService={assignmentService} capabilities={capabilities}
capabilities={capabilities} assignableTypes={assignableTypes}
assignableTypes={assignableTypes} />
/> </RedirectToHomeIfUnauthorized>
</RedirectToHomeIfUnauthorized> </KibanaRenderContextProvider>,
</KibanaThemeProvider>
</I18nProvider>,
element element
); );

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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