diff --git a/examples/developer_examples/public/app.tsx b/examples/developer_examples/public/app.tsx index 0f0c0e4429356..0e915eeccf1ec 100644 --- a/examples/developer_examples/public/app.tsx +++ b/examples/developer_examples/public/app.tsx @@ -28,6 +28,7 @@ import { AppMountParameters, I18nStart, ThemeServiceStart, + UserProfileService, } from '@kbn/core/public'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { ExampleDefinition } from './types'; @@ -36,6 +37,7 @@ interface StartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } interface Props { diff --git a/examples/developer_examples/public/plugin.ts b/examples/developer_examples/public/plugin.ts index b7f676ad9a71a..478da722775a5 100644 --- a/examples/developer_examples/public/plugin.ts +++ b/examples/developer_examples/public/plugin.ts @@ -28,10 +28,10 @@ export class DeveloperExamplesPlugin implements Plugin coreStart.application.navigateToApp(appId), getUrlForApp: (appId: string) => coreStart.application.getUrlForApp(appId), diff --git a/examples/routing_example/public/services.ts b/examples/routing_example/public/services.ts index 7ec7d408c1b6b..ac6bfbc5f1690 100644 --- a/examples/routing_example/public/services.ts +++ b/examples/routing_example/public/services.ts @@ -12,6 +12,7 @@ import type { CoreStart, I18nStart, ThemeServiceStart, + UserProfileService, } from '@kbn/core/public'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import { @@ -25,6 +26,7 @@ interface StartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } export interface Services { @@ -37,8 +39,8 @@ export interface Services { } export function getServices(core: CoreStart): Services { - const { analytics, i18n, theme } = core; - const startServices = { analytics, i18n, theme }; + const { analytics, i18n, theme, userProfile } = core; + const startServices = { analytics, i18n, theme, userProfile }; return { startServices, diff --git a/examples/ui_action_examples/public/hello_world_action.tsx b/examples/ui_action_examples/public/hello_world_action.tsx index 7597ec75a2fe0..52a808ed48641 100644 --- a/examples/ui_action_examples/public/hello_world_action.tsx +++ b/examples/ui_action_examples/public/hello_world_action.tsx @@ -14,7 +14,7 @@ import { toMountPoint } from '@kbn/react-kibana-mount'; export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD'; -type StartServices = Pick; +type StartServices = Pick; export const createHelloWorldActionDefinition = ( getStartServices: () => Promise diff --git a/examples/ui_actions_explorer/public/hello_world_example.tsx b/examples/ui_actions_explorer/public/hello_world_example.tsx index bcf4ed7e24fe5..33b201e83adcf 100644 --- a/examples/ui_actions_explorer/public/hello_world_example.tsx +++ b/examples/ui_actions_explorer/public/hello_world_example.tsx @@ -19,7 +19,7 @@ const DYNAMIC_ACTION_ID = `${ACTION_HELLO_WORLD}-Waldo`; interface Props { uiActionsStartService: UiActionsStart; - startServices: Pick; + startServices: Pick; } export const HelloWorldExample = ({ uiActionsStartService, startServices }: Props) => { diff --git a/packages/cloud/connection_details/kibana/global.ts b/packages/cloud/connection_details/kibana/global.ts index 40c883bc06375..5bd205c7bf459 100644 --- a/packages/cloud/connection_details/kibana/global.ts +++ b/packages/cloud/connection_details/kibana/global.ts @@ -21,6 +21,7 @@ export interface ConnectionDetailsGlobalDependencies { http: CoreStart['http']; application: CoreStart['application']; overlays: CoreStart['overlays']; + userProfile: CoreStart['userProfile']; }; plugins: { cloud?: CloudStart; diff --git a/packages/cloud/connection_details/kibana/open_connection_details.tsx b/packages/cloud/connection_details/kibana/open_connection_details.tsx index 8d231e2645ab0..f055a8ddaf70f 100644 --- a/packages/cloud/connection_details/kibana/open_connection_details.tsx +++ b/packages/cloud/connection_details/kibana/open_connection_details.tsx @@ -21,6 +21,7 @@ export interface OpenConnectionDetailsParams { i18n: CoreStart['i18n']; analytics?: CoreStart['analytics']; theme: CoreStart['theme']; + userProfile: CoreStart['userProfile']; }; }; } diff --git a/packages/content-management/content_editor/src/services.tsx b/packages/content-management/content_editor/src/services.tsx index ee0e66b10300c..7170940665188 100644 --- a/packages/content-management/content_editor/src/services.tsx +++ b/packages/content-management/content_editor/src/services.tsx @@ -20,6 +20,7 @@ import type { I18nStart } from '@kbn/core-i18n-browser'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; import type { OverlayFlyoutOpenOptions } from '@kbn/core-overlays-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { toMountPoint } from '@kbn/react-kibana-mount'; type NotifyFn = (title: JSX.Element, text?: string) => void; @@ -68,6 +69,7 @@ interface ContentEditorStartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } /** diff --git a/packages/content-management/content_editor/tsconfig.json b/packages/content-management/content_editor/tsconfig.json index 565535ec85b3e..832da409a06fd 100644 --- a/packages/content-management/content_editor/tsconfig.json +++ b/packages/content-management/content_editor/tsconfig.json @@ -30,6 +30,7 @@ "@kbn/test-jest-helpers", "@kbn/react-kibana-mount", "@kbn/content-management-user-profiles", + "@kbn/core-user-profile-browser", ], "exclude": [ "target/**/*" diff --git a/packages/content-management/table_list_view_table/src/services.tsx b/packages/content-management/table_list_view_table/src/services.tsx index ab6e875789278..a8c3d3cc9f60b 100644 --- a/packages/content-management/table_list_view_table/src/services.tsx +++ b/packages/content-management/table_list_view_table/src/services.tsx @@ -24,7 +24,7 @@ import type { I18nStart } from '@kbn/core-i18n-browser'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; import type { OverlayFlyoutOpenOptions } from '@kbn/core-overlays-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; -import type { UserProfileServiceStart } from '@kbn/core-user-profile-browser'; +import type { UserProfileService, UserProfileServiceStart } from '@kbn/core-user-profile-browser'; import type { FormattedRelative } from '@kbn/i18n-react'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { RedirectAppLinksKibanaProvider } from '@kbn/shared-ux-link-redirect-app'; @@ -100,6 +100,7 @@ interface TableListViewStartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } /** diff --git a/packages/core/apps/core-apps-browser-internal/src/core_app.ts b/packages/core/apps/core-apps-browser-internal/src/core_app.ts index 419efaef039fe..87f921133421b 100644 --- a/packages/core/apps/core-apps-browser-internal/src/core_app.ts +++ b/packages/core/apps/core-apps-browser-internal/src/core_app.ts @@ -22,6 +22,7 @@ import type { import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { renderApp as renderStatusApp } from './status'; import { renderApp as renderErrorApp, @@ -45,6 +46,7 @@ export interface CoreAppsServiceStartDeps { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; } export class CoreAppsService { @@ -86,9 +88,7 @@ export class CoreAppsService { http, notifications, uiSettings, - analytics, - i18n, - theme, + ...startDeps }: CoreAppsServiceStartDeps) { if (!application.history) { return; @@ -101,7 +101,7 @@ export class CoreAppsService { uiSettings, }); - setupPublicBaseUrlConfigWarning({ docLinks, http, notifications, analytics, i18n, theme }); + setupPublicBaseUrlConfigWarning({ docLinks, http, notifications, ...startDeps }); } public stop() { diff --git a/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.test.tsx b/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.test.tsx index 58743f339accc..20159d54116a4 100644 --- a/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.test.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.test.tsx @@ -13,6 +13,7 @@ import { httpServiceMock } from '@kbn/core-http-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { setupPublicBaseUrlConfigWarning } from './public_base_url'; @@ -22,12 +23,8 @@ describe('publicBaseUrl warning', () => { const i18nStart = i18nServiceMock.createStartContract(); const analytics = analyticsServiceMock.createAnalyticsServiceStart(); const theme = themeServiceMock.createStartContract(); - const startServices = { - notifications, - analytics, - i18n: i18nStart, - theme, - }; + const userProfile = userProfileServiceMock.createStart(); + const startServices = { notifications, analytics, i18n: i18nStart, theme, userProfile }; const addWarningToastSpy = jest.spyOn(notifications.toasts, 'addWarning'); beforeEach(() => { diff --git a/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.tsx b/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.tsx index 758c85ed04816..a0b8baf8e815c 100644 --- a/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/errors/public_base_url.tsx @@ -16,6 +16,7 @@ import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { InternalHttpStart } from '@kbn/core-http-browser-internal'; import type { NotificationsStart } from '@kbn/core-notifications-browser'; import { mountReactNode } from '@kbn/core-mount-utils-browser-internal'; @@ -35,6 +36,7 @@ interface Deps { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; } export const setupPublicBaseUrlConfigWarning = ({ diff --git a/packages/core/apps/core-apps-browser-internal/tsconfig.json b/packages/core/apps/core-apps-browser-internal/tsconfig.json index 9902b12732760..499f4b975f6d8 100644 --- a/packages/core/apps/core-apps-browser-internal/tsconfig.json +++ b/packages/core/apps/core-apps-browser-internal/tsconfig.json @@ -40,7 +40,9 @@ "@kbn/react-kibana-context-render", "@kbn/core-analytics-browser-mocks", "@kbn/core-i18n-browser-mocks", - "@kbn/core-theme-browser-mocks" + "@kbn/core-theme-browser-mocks", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks" ], "exclude": [ "target/**/*" diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx index 4994302c2e756..ade55365409cb 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx @@ -24,6 +24,7 @@ import { customBrandingServiceMock } from '@kbn/core-custom-branding-browser-moc import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { getAppInfo } from '@kbn/core-application-browser-internal'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { findTestSubject } from '@kbn/test-jest-helpers'; @@ -55,6 +56,7 @@ function defaultStartDeps(availableApps?: App[], currentAppId?: string) { analytics: analyticsServiceMock.createAnalyticsServiceStart(), i18n: i18nServiceMock.createStartContract(), theme: themeServiceMock.createStartContract(), + userProfile: userProfileServiceMock.createStart(), application: applicationServiceMock.createInternalStartContract(currentAppId), docLinks: docLinksServiceMock.createStartContract(), http: httpServiceMock.createStartContract(), diff --git a/packages/core/chrome/core-chrome-browser-internal/tsconfig.json b/packages/core/chrome/core-chrome-browser-internal/tsconfig.json index d4512b515f640..ca9e5d5576ad9 100644 --- a/packages/core/chrome/core-chrome-browser-internal/tsconfig.json +++ b/packages/core/chrome/core-chrome-browser-internal/tsconfig.json @@ -55,6 +55,7 @@ "@kbn/core-theme-browser-mocks", "@kbn/react-kibana-context-render", "@kbn/recently-accessed", + "@kbn/core-user-profile-browser-mocks", ], "exclude": [ "target/**/*", diff --git a/packages/core/notifications/core-notifications-browser-internal/src/notifications_service.ts b/packages/core/notifications/core-notifications-browser-internal/src/notifications_service.ts index 280dd9887b995..a9abdcedede5f 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/notifications_service.ts +++ b/packages/core/notifications/core-notifications-browser-internal/src/notifications_service.ts @@ -12,6 +12,7 @@ import { i18n } from '@kbn/i18n'; import { Subscription } from 'rxjs'; import type { AnalyticsServiceStart, AnalyticsServiceSetup } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { OverlayStart } from '@kbn/core-overlays-browser'; @@ -29,6 +30,7 @@ export interface StartDeps { i18n: I18nStart; overlays: OverlayStart; theme: ThemeServiceStart; + userProfile: UserProfileService; analytics: AnalyticsServiceStart; targetDomElement: HTMLElement; } @@ -62,36 +64,26 @@ export class NotificationsService { return notificationSetup; } - public start({ - analytics, - i18n: i18nDep, - overlays, - theme, - targetDomElement, - }: StartDeps): NotificationsStart { + public start({ overlays, targetDomElement, ...startDeps }: StartDeps): NotificationsStart { this.targetDomElement = targetDomElement; const toastsContainer = document.createElement('div'); targetDomElement.appendChild(toastsContainer); - const eventReporter = new EventReporter({ analytics }); + const eventReporter = new EventReporter({ analytics: startDeps.analytics }); return { toasts: this.toasts.start({ eventReporter, - i18n: i18nDep, overlays, - analytics, - theme, targetDomElement: toastsContainer, + ...startDeps, }), showErrorDialog: ({ title, error }) => showErrorDialog({ title, error, openModal: overlays.openModal, - analytics, - i18n: i18nDep, - theme, + ...startDeps, }), }; } diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/__snapshots__/error_toast.test.tsx.snap b/packages/core/notifications/core-notifications-browser-internal/src/toasts/__snapshots__/error_toast.test.tsx.snap index cb82dd49db745..73b165848162e 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/__snapshots__/error_toast.test.tsx.snap +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/__snapshots__/error_toast.test.tsx.snap @@ -29,6 +29,16 @@ exports[`renders matching snapshot 1`] = ` }, } } + userProfile={ + Object { + "bulkGet": [MockFunction], + "getCurrent": [MockFunction], + "getUserProfile$": [MockFunction], + "partialUpdate": [MockFunction], + "suggest": [MockFunction], + "update": [MockFunction], + } + } >

(openModal = jest.fn())); @@ -39,6 +41,7 @@ function render(props: ErrorToastProps = {}) { analytics={mockAnalytics} i18n={mockI18n} theme={mockTheme} + userProfile={mockUserProfile} /> ); } diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/error_toast.tsx b/packages/core/notifications/core-notifications-browser-internal/src/toasts/error_toast.tsx index c8c914f2ef9d7..2805fc2bc14a8 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/error_toast.tsx +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/error_toast.tsx @@ -25,11 +25,13 @@ import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { OverlayStart } from '@kbn/core-overlays-browser'; import { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; interface StartServices { analytics: AnalyticsServiceStart; i18n: I18nStart; + userProfile: UserProfileService; theme: ThemeServiceStart; } @@ -62,7 +64,10 @@ export function showErrorDialog({ error, openModal, ...startServices -}: Pick) { +}: Pick< + ErrorToastProps, + 'error' | 'title' | 'openModal' | 'analytics' | 'i18n' | 'userProfile' | 'theme' +>) { let text = ''; if (isRequestError(error)) { diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.test.ts b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.test.ts index 503bdb63578da..253c6376eb9b1 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.test.ts +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.test.ts @@ -12,8 +12,10 @@ import { firstValueFrom } from 'rxjs'; import { ToastsApi } from './toasts_api'; import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; +import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; async function getCurrentToasts(toasts: ToastsApi) { return await firstValueFrom(toasts.get$()); @@ -45,8 +47,10 @@ function toastDeps() { function startDeps() { return { overlays: {} as any, + analytics: analyticsServiceMock.createAnalyticsServiceStart(), i18n: i18nServiceMock.createStartContract(), theme: themeServiceMock.createStartContract(), + userProfile: userProfileServiceMock.createStart(), }; } diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.tsx b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.tsx index 7d6ab2f93b88f..ece936f0cf6ce 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.tsx +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_api.tsx @@ -24,7 +24,8 @@ import type { ToastInputFields, ToastOptions, } from '@kbn/core-notifications-browser'; -import { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { ErrorToast } from './error_toast'; const normalizeToast = (toastOrTitle: ToastInput): ToastInputFields => { @@ -36,6 +37,14 @@ const normalizeToast = (toastOrTitle: ToastInput): ToastInputFields => { return omitBy(toastOrTitle, isUndefined); }; +interface StartDeps { + analytics: AnalyticsServiceStart; + overlays: OverlayStart; + i18n: I18nStart; + theme: ThemeServiceStart; + userProfile: UserProfileService; +} + /** * Methods for adding and removing global toast messages. * @public @@ -45,28 +54,15 @@ export class ToastsApi implements IToasts { private idCounter = 0; private uiSettings: IUiSettingsClient; - private overlays?: OverlayStart; - private analytics?: AnalyticsServiceStart; - private i18n?: I18nStart; - private theme?: ThemeServiceStart; + private startDeps?: StartDeps; constructor(deps: { uiSettings: IUiSettingsClient }) { this.uiSettings = deps.uiSettings; } /** @internal */ - public start({ - overlays, - i18n, - theme, - }: { - overlays: OverlayStart; - i18n: I18nStart; - theme: ThemeServiceStart; - }) { - this.overlays = overlays; - this.i18n = i18n; - this.theme = theme; + public start(startDeps: StartDeps) { + this.startDeps = startDeps; } /** Observable of the toast messages to show to the user. */ @@ -190,9 +186,7 @@ export class ToastsApi implements IToasts { error={error} title={options.title} toastMessage={message} - analytics={this.analytics!} - i18n={this.i18n!} - theme={this.theme!} + {...this.startDeps!} /> ), ...options, @@ -202,12 +196,13 @@ export class ToastsApi implements IToasts { private openModal( ...args: Parameters ): ReturnType { - if (!this.overlays) { + const { overlays } = this.startDeps ?? {}; + if (!overlays) { // This case should never happen because no rendering should be occurring // before the ToastService is started. throw new Error(`Modal opened before ToastService was started.`); } - return this.overlays.openModal(...args); + return overlays.openModal(...args); } } diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.test.tsx b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.test.tsx index 4fa2d6f27db73..d350b9b8d62ca 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.test.tsx +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.test.tsx @@ -13,6 +13,7 @@ import { ToastsService } from './toasts_service'; import { ToastsApi } from './toasts_api'; import { overlayServiceMock } from '@kbn/core-overlays-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { EventReporter } from './telemetry'; @@ -25,6 +26,7 @@ const mockI18n: any = { const mockOverlays = overlayServiceMock.createStartContract(); const mockTheme = themeServiceMock.createStartContract(); +const mockUserProfile = userProfileServiceMock.createStart(); const mockAnalytics = analyticsServiceMock.createAnalyticsServiceStart(); const eventReporter = new EventReporter({ analytics: mockAnalytics }); @@ -51,6 +53,7 @@ describe('#start()', () => { analytics: mockAnalytics, i18n: mockI18n, theme: mockTheme, + userProfile: mockUserProfile, targetDomElement, overlays: mockOverlays, eventReporter, @@ -70,6 +73,7 @@ describe('#start()', () => { analytics: mockAnalytics, i18n: mockI18n, theme: mockTheme, + userProfile: mockUserProfile, targetDomElement, overlays: mockOverlays, eventReporter, @@ -89,6 +93,7 @@ describe('#stop()', () => { analytics: mockAnalytics, i18n: mockI18n, theme: mockTheme, + userProfile: mockUserProfile, targetDomElement, overlays: mockOverlays, eventReporter, @@ -115,6 +120,7 @@ describe('#stop()', () => { analytics: mockAnalytics, i18n: mockI18n, theme: mockTheme, + userProfile: mockUserProfile, targetDomElement, overlays: mockOverlays, eventReporter, diff --git a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.tsx b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.tsx index 44166df388c4c..c37313e9613c1 100644 --- a/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.tsx +++ b/packages/core/notifications/core-notifications-browser-internal/src/toasts/toasts_service.tsx @@ -12,6 +12,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { OverlayStart } from '@kbn/core-overlays-browser'; @@ -29,6 +30,7 @@ interface StartDeps { i18n: I18nStart; overlays: OverlayStart; theme: ThemeServiceStart; + userProfile: UserProfileService; eventReporter: EventReporter; targetDomElement: HTMLElement; } @@ -42,12 +44,12 @@ export class ToastsService { return this.api!; } - public start({ eventReporter, analytics, i18n, overlays, theme, targetDomElement }: StartDeps) { - this.api!.start({ overlays, i18n, theme }); + public start({ eventReporter, overlays, targetDomElement, ...startDeps }: StartDeps) { + this.api!.start({ overlays, ...startDeps }); this.targetDomElement = targetDomElement; render( - + this.api!.remove(toastId)} toasts$={this.api!.get$()} diff --git a/packages/core/notifications/core-notifications-browser-internal/tsconfig.json b/packages/core/notifications/core-notifications-browser-internal/tsconfig.json index c3582c1b8925b..0aa4081925399 100644 --- a/packages/core/notifications/core-notifications-browser-internal/tsconfig.json +++ b/packages/core/notifications/core-notifications-browser-internal/tsconfig.json @@ -30,7 +30,9 @@ "@kbn/core-mount-utils-browser", "@kbn/react-kibana-context-render", "@kbn/core-analytics-browser", - "@kbn/core-analytics-browser-mocks" + "@kbn/core-analytics-browser-mocks", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks" ], "exclude": [ "target/**/*", diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.test.ts b/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.test.ts index 40174b5dcff42..d54902ed8ad9d 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.test.ts +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.test.ts @@ -13,6 +13,7 @@ import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; describe('OverlayBannersService', () => { let service: InternalOverlayBannersStart; @@ -22,6 +23,7 @@ describe('OverlayBannersService', () => { i18n: i18nServiceMock.createStartContract(), theme: themeServiceMock.createStartContract(), uiSettings: uiSettingsServiceMock.createStartContract(), + userProfile: userProfileServiceMock.createStart(), }); }); diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.tsx b/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.tsx index 31a43407ba8be..5147d49e897c7 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.tsx +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/banners_service.tsx @@ -14,6 +14,7 @@ import { map } from 'rxjs'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { MountPoint } from '@kbn/core-mount-utils-browser'; import type { OverlayBannersStart } from '@kbn/core-overlays-browser'; @@ -25,6 +26,7 @@ interface StartServices { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; } interface StartDeps extends StartServices { diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts index 9297e645a033f..a9023f025d4ba 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts @@ -13,6 +13,7 @@ import { overlayBannersServiceMock } from './banners_service.test.mocks'; import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { Subject } from 'rxjs'; describe('OverlayBannersService', () => { @@ -20,6 +21,7 @@ describe('OverlayBannersService', () => { let service: UserBannerService; let uiSettings: ReturnType; let banners: ReturnType; + let userProfile: ReturnType; const startService = (content?: string) => { bannerContent = content; @@ -40,6 +42,7 @@ describe('OverlayBannersService', () => { i18n: i18nServiceMock.createStartContract(), theme: themeServiceMock.createStartContract(), uiSettings, + userProfile, }); }; diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx index 7b7c2e45e8e39..94bc96c9b0c05 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx @@ -17,6 +17,7 @@ import { EuiCallOut, EuiButton, EuiLoadingSpinner } from '@elastic/eui'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { OverlayBannersStart } from '@kbn/core-overlays-browser'; @@ -26,6 +27,7 @@ interface StartServices { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; } interface StartDeps extends StartServices { diff --git a/packages/core/overlays/core-overlays-browser-internal/src/flyout/__snapshots__/flyout_service.test.tsx.snap b/packages/core/overlays/core-overlays-browser-internal/src/flyout/__snapshots__/flyout_service.test.tsx.snap index a41da1f45af56..9df54435ba9a0 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/flyout/__snapshots__/flyout_service.test.tsx.snap +++ b/packages/core/overlays/core-overlays-browser-internal/src/flyout/__snapshots__/flyout_service.test.tsx.snap @@ -39,6 +39,16 @@ Array [ }, } } + userProfile={ + Object { + "bulkGet": [MockFunction], + "getCurrent": [MockFunction], + "getUserProfile$": [MockFunction], + "partialUpdate": [MockFunction], + "suggest": [MockFunction], + "update": [MockFunction], + } + } > { mockReactDomRender.mockClear(); @@ -39,6 +41,7 @@ const getServiceStart = () => { analytics: analyticsMock, i18n: i18nMock, theme: themeMock, + userProfile: userProfileMock, targetDomElement: document.createElement('div'), }); }; diff --git a/packages/core/overlays/core-overlays-browser-internal/src/flyout/flyout_service.tsx b/packages/core/overlays/core-overlays-browser-internal/src/flyout/flyout_service.tsx index 3cd9cc29c1001..b98e6c05ae50c 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/flyout/flyout_service.tsx +++ b/packages/core/overlays/core-overlays-browser-internal/src/flyout/flyout_service.tsx @@ -15,6 +15,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { Subject } from 'rxjs'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; import { MountWrapper } from '@kbn/core-mount-utils-browser-internal'; @@ -65,6 +66,7 @@ interface StartDeps { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; targetDomElement: Element; } @@ -73,7 +75,13 @@ export class FlyoutService { private activeFlyout: FlyoutRef | null = null; private targetDomElement: Element | null = null; - public start({ analytics, i18n, theme, targetDomElement }: StartDeps): OverlayFlyoutStart { + public start({ + analytics, + i18n, + theme, + userProfile, + targetDomElement, + }: StartDeps): OverlayFlyoutStart { this.targetDomElement = targetDomElement; return { @@ -121,7 +129,12 @@ export class FlyoutService { }; render( - + {getWrapper()} , this.targetDomElement diff --git a/packages/core/overlays/core-overlays-browser-internal/src/modal/__snapshots__/modal_service.test.tsx.snap b/packages/core/overlays/core-overlays-browser-internal/src/modal/__snapshots__/modal_service.test.tsx.snap index 5b1bb22336493..cc2dc671f9210 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/modal/__snapshots__/modal_service.test.tsx.snap +++ b/packages/core/overlays/core-overlays-browser-internal/src/modal/__snapshots__/modal_service.test.tsx.snap @@ -108,6 +108,16 @@ Array [ }, } } + userProfile={ + Object { + "bulkGet": [MockFunction], + "getCurrent": [MockFunction], + "getUserProfile$": [MockFunction], + "partialUpdate": [MockFunction], + "suggest": [MockFunction], + "update": [MockFunction], + } + } > { mockReactDomRender.mockClear(); @@ -34,6 +36,7 @@ const getServiceStart = () => { analytics: analyticsMock, i18n: i18nMock, theme: themeMock, + userProfile: userProfileMock, targetDomElement: document.createElement('div'), }); }; diff --git a/packages/core/overlays/core-overlays-browser-internal/src/modal/modal_service.tsx b/packages/core/overlays/core-overlays-browser-internal/src/modal/modal_service.tsx index 8158f1c383116..d81c4cfdb41f5 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/modal/modal_service.tsx +++ b/packages/core/overlays/core-overlays-browser-internal/src/modal/modal_service.tsx @@ -16,6 +16,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { Subject } from 'rxjs'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser'; import { MountWrapper } from '@kbn/core-mount-utils-browser-internal'; @@ -58,6 +59,7 @@ class ModalRef implements OverlayRef { interface StartDeps { i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; analytics: AnalyticsServiceStart; targetDomElement: Element; } @@ -67,7 +69,7 @@ export class ModalService { private activeModal: ModalRef | null = null; private targetDomElement: Element | null = null; - public start({ analytics, i18n, theme, targetDomElement }: StartDeps): OverlayModalStart { + public start({ targetDomElement, ...startDeps }: StartDeps): OverlayModalStart { this.targetDomElement = targetDomElement; return { @@ -90,7 +92,7 @@ export class ModalService { this.activeModal = modal; render( - + modal.close()}> @@ -150,7 +152,7 @@ export class ModalService { }; render( - + , targetDomElement diff --git a/packages/core/overlays/core-overlays-browser-internal/src/overlay_service.ts b/packages/core/overlays/core-overlays-browser-internal/src/overlay_service.ts index 68b3eac75e3ee..1501cd19cf7d4 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/overlay_service.ts +++ b/packages/core/overlays/core-overlays-browser-internal/src/overlay_service.ts @@ -9,6 +9,7 @@ import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { OverlayStart } from '@kbn/core-overlays-browser'; @@ -17,10 +18,11 @@ import { FlyoutService } from './flyout'; import { ModalService } from './modal'; interface StartDeps { + targetDomElement: HTMLElement; analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; - targetDomElement: HTMLElement; + userProfile: UserProfileService; uiSettings: IUiSettingsClient; } @@ -30,25 +32,21 @@ export class OverlayService { private modalService = new ModalService(); private flyoutService = new FlyoutService(); - public start({ analytics, i18n, targetDomElement, uiSettings, theme }: StartDeps): OverlayStart { + public start({ targetDomElement, ...startDeps }: StartDeps): OverlayStart { const flyoutElement = document.createElement('div'); targetDomElement.appendChild(flyoutElement); const flyouts = this.flyoutService.start({ - analytics, - i18n, - theme, targetDomElement: flyoutElement, + ...startDeps, }); - const banners = this.bannersService.start({ uiSettings, analytics, i18n, theme }); + const banners = this.bannersService.start(startDeps); const modalElement = document.createElement('div'); targetDomElement.appendChild(modalElement); const modals = this.modalService.start({ - analytics, - i18n, - theme, targetDomElement: modalElement, + ...startDeps, }); return { diff --git a/packages/core/overlays/core-overlays-browser-internal/tsconfig.json b/packages/core/overlays/core-overlays-browser-internal/tsconfig.json index 3a2034b6512ea..3604db4bc64f7 100644 --- a/packages/core/overlays/core-overlays-browser-internal/tsconfig.json +++ b/packages/core/overlays/core-overlays-browser-internal/tsconfig.json @@ -27,6 +27,8 @@ "@kbn/react-kibana-context-render", "@kbn/core-analytics-browser-mocks", "@kbn/core-analytics-browser", + "@kbn/core-user-profile-browser-mocks", + "@kbn/core-user-profile-browser", ], "exclude": [ "target/**/*", diff --git a/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.test.tsx b/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.test.tsx index f6e8685b122dc..993d1177ec2bf 100644 --- a/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.test.tsx +++ b/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.test.tsx @@ -15,6 +15,7 @@ import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { applicationServiceMock } from '@kbn/core-application-browser-mocks'; import { chromeServiceMock } from '@kbn/core-chrome-browser-mocks'; import { overlayServiceMock } from '@kbn/core-overlays-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { RenderingService } from './rendering_service'; @@ -26,6 +27,7 @@ describe('RenderingService#start', () => { let overlays: ReturnType; let i18n: ReturnType; let theme: ReturnType; + let userProfile: ReturnType; let targetDomElement: HTMLDivElement; let rendering: RenderingService; @@ -41,8 +43,8 @@ describe('RenderingService#start', () => { overlays = overlayServiceMock.createStartContract(); overlays.banners.getComponent.mockReturnValue(

I'm a banner!
); + userProfile = userProfileServiceMock.createStart(); theme = themeServiceMock.createStartContract(); - i18n = i18nServiceMock.createStartContract(); targetDomElement = document.createElement('div'); @@ -58,6 +60,7 @@ describe('RenderingService#start', () => { overlays, i18n, theme, + userProfile, targetDomElement, }); }; diff --git a/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.tsx b/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.tsx index 12a597ba9318f..1995d6c013cf6 100644 --- a/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.tsx +++ b/packages/core/rendering/core-rendering-browser-internal/src/rendering_service.tsx @@ -17,6 +17,7 @@ import type { InternalChromeStart } from '@kbn/core-chrome-browser-internal'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { OverlayStart } from '@kbn/core-overlays-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root'; import { APP_FIXED_VIEWPORT_ID } from '@kbn/core-rendering-browser'; import { AppWrapper } from './app_containers'; @@ -25,6 +26,7 @@ interface StartServices { analytics: AnalyticsServiceStart; i18n: I18nStart; theme: ThemeServiceStart; + userProfile: UserProfileService; } export interface StartDeps extends StartServices { diff --git a/packages/core/rendering/core-rendering-browser-internal/tsconfig.json b/packages/core/rendering/core-rendering-browser-internal/tsconfig.json index 4b0c009a0a033..02657e4e54b43 100644 --- a/packages/core/rendering/core-rendering-browser-internal/tsconfig.json +++ b/packages/core/rendering/core-rendering-browser-internal/tsconfig.json @@ -27,7 +27,9 @@ "@kbn/core-analytics-browser", "@kbn/core-i18n-browser", "@kbn/core-theme-browser", - "@kbn/core-rendering-browser" + "@kbn/core-rendering-browser", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks" ], "exclude": [ "target/**/*", diff --git a/packages/core/root/core-root-browser-internal/src/core_system.test.ts b/packages/core/root/core-root-browser-internal/src/core_system.test.ts index 877795ff0b459..cb739ec7c8d41 100644 --- a/packages/core/root/core-root-browser-internal/src/core_system.test.ts +++ b/packages/core/root/core-root-browser-internal/src/core_system.test.ts @@ -469,6 +469,7 @@ describe('#start()', () => { i18n: expect.any(Object), overlays: expect.any(Object), theme: expect.any(Object), + userProfile: expect.any(Object), targetDomElement: expect.any(HTMLElement), analytics: expect.any(Object), }); @@ -494,6 +495,7 @@ describe('#start()', () => { overlays: expect.any(Object), i18n: expect.any(Object), theme: expect.any(Object), + userProfile: expect.any(Object), targetDomElement: expect.any(HTMLElement), }); }); diff --git a/packages/core/root/core-root-browser-internal/src/core_system.ts b/packages/core/root/core-root-browser-internal/src/core_system.ts index 44e25b257e32c..38532948ea505 100644 --- a/packages/core/root/core-root-browser-internal/src/core_system.ts +++ b/packages/core/root/core-root-browser-internal/src/core_system.ts @@ -319,6 +319,7 @@ export class CoreSystem { analytics, theme, uiSettings, + userProfile, targetDomElement: overlayTargetDomElement, }); const notifications = this.notifications.start({ @@ -326,6 +327,7 @@ export class CoreSystem { i18n, overlays, theme, + userProfile, targetDomElement: notificationsTargetDomElement, }); const customBranding = this.customBranding.start(); @@ -360,6 +362,7 @@ export class CoreSystem { analytics, i18n, theme, + userProfile, }); const featureFlags = await this.featureFlags.start(); @@ -404,6 +407,7 @@ export class CoreSystem { overlays, theme, targetDomElement: coreUiTargetDomElement, + userProfile, }); performance.mark(KBN_LOAD_MARKS, { diff --git a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.test.tsx b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.test.tsx index a3e4516b07510..584d917ac953d 100644 --- a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.test.tsx +++ b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.test.tsx @@ -14,14 +14,20 @@ import { of, BehaviorSubject } from 'rxjs'; import { useEuiTheme } from '@elastic/eui'; import type { UseEuiTheme } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; + +import type { UserProfileService } from '@kbn/core-user-profile-browser'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; + import type { CoreTheme } from '@kbn/core-theme-browser'; import { CoreThemeProvider } from './core_theme_provider'; describe('CoreThemeProvider', () => { let euiTheme: UseEuiTheme | undefined; + let userProfile: UserProfileService; beforeEach(() => { euiTheme = undefined; + userProfile = userProfileServiceMock.createStart(); }); const flushPromises = async () => { @@ -53,7 +59,7 @@ describe('CoreThemeProvider', () => { const coreTheme: CoreTheme = { darkMode: true, name: 'amsterdam' }; const wrapper = mountWithIntl( - + ); @@ -67,7 +73,7 @@ describe('CoreThemeProvider', () => { const coreTheme$ = new BehaviorSubject({ darkMode: true, name: 'amsterdam' }); const wrapper = mountWithIntl( - + ); diff --git a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx index 7a77928fecfa1..0cef81aeca618 100644 --- a/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx +++ b/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx @@ -10,10 +10,12 @@ import React, { type FC, type PropsWithChildren } from 'react'; import { CoreTheme } from '@kbn/core-theme-browser/src/types'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { Observable } from 'rxjs'; interface CoreThemeProviderProps { theme$: Observable; + userProfile: UserProfileService; globalStyles?: boolean; } @@ -24,8 +26,11 @@ interface CoreThemeProviderProps { */ export const CoreThemeProvider: FC> = ({ theme$, + userProfile, globalStyles, children, }) => ( - {children} + + {children} + ); diff --git a/packages/core/theme/core-theme-browser-internal/tsconfig.json b/packages/core/theme/core-theme-browser-internal/tsconfig.json index 8bd8824eb872b..0289639ddbf83 100644 --- a/packages/core/theme/core-theme-browser-internal/tsconfig.json +++ b/packages/core/theme/core-theme-browser-internal/tsconfig.json @@ -20,6 +20,8 @@ "@kbn/react-kibana-context-theme", "@kbn/core-injected-metadata-common-internal", "@kbn/ui-theme", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks", ], "exclude": [ "target/**/*", diff --git a/packages/core/user-profile/core-user-profile-browser-mocks/src/user_profile_service.mock.ts b/packages/core/user-profile/core-user-profile-browser-mocks/src/user_profile_service.mock.ts index 7a84f59a5414a..8f86d8ac6555f 100644 --- a/packages/core/user-profile/core-user-profile-browser-mocks/src/user_profile_service.mock.ts +++ b/packages/core/user-profile/core-user-profile-browser-mocks/src/user_profile_service.mock.ts @@ -7,6 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ +import { of } from 'rxjs'; import type { UserProfileServiceSetup, UserProfileServiceStart, @@ -26,7 +27,7 @@ const createSetupMock = () => { const createStartMock = () => { const mock: jest.Mocked = { - getUserProfile$: jest.fn(), + getUserProfile$: jest.fn().mockReturnValue(of(null)), getCurrent: jest.fn(), bulkGet: jest.fn(), suggest: jest.fn(), @@ -47,7 +48,7 @@ const createInternalSetupMock = () => { const createInternalStartMock = () => { const mock: jest.Mocked = { - getUserProfile$: jest.fn(), + getUserProfile$: jest.fn().mockReturnValue(of(null)), getCurrent: jest.fn(), bulkGet: jest.fn(), suggest: jest.fn(), diff --git a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx index 19c6a190485e1..0b00f86e23f7b 100644 --- a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx +++ b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx @@ -15,7 +15,6 @@ import { CoreStart, I18nStart, NotificationsSetup, - ThemeServiceSetup, } from '@kbn/core/public'; import { DataPublicPluginStart, SerializedSearchSourceFields } from '@kbn/data-plugin/public'; import { @@ -59,6 +58,7 @@ type StartServices = [ | 'analytics' | 'i18n' | 'theme' + | 'userProfile' // used extensively in Reporting share panel action | 'application' | 'uiSettings' @@ -101,14 +101,12 @@ export class ReportingCsvPanelAction implements ActionDefinition; private readonly notifications: NotificationsSetup; private readonly apiClient: ReportingAPIClient; - private readonly theme: ThemeServiceSetup; - private readonly startServices$: Params['startServices$']; + private readonly startServices$: Observable; constructor({ core, apiClient, startServices$ }: Params) { this.isDownloading = false; this.apiClient = apiClient; this.notifications = core.notifications; - this.theme = core.theme; this.startServices$ = startServices$; this.i18nStrings = getI18nStrings(apiClient); } @@ -148,7 +146,8 @@ export class ReportingCsvPanelAction implements ActionDefinition { - const { searchSource, columns, title, analytics, i18nStart } = params; + const [startServices] = await firstValueFrom(this.startServices$); + const { searchSource, columns, title } = params; const csvJobParams = this.apiClient.getDecoratedJobParams({ searchSource, columns, @@ -162,11 +161,7 @@ export class ReportingCsvPanelAction implements ActionDefinition, diff --git a/packages/kbn-storybook/src/lib/decorators.tsx b/packages/kbn-storybook/src/lib/decorators.tsx index 270da371172eb..162200e83ef41 100644 --- a/packages/kbn-storybook/src/lib/decorators.tsx +++ b/packages/kbn-storybook/src/lib/decorators.tsx @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { Subject } from 'rxjs'; +import { of, Subject } from 'rxjs'; import React, { useEffect } from 'react'; import { action } from '@storybook/addon-actions'; import type { DecoratorFn } from '@storybook/react'; @@ -22,6 +22,7 @@ import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root'; import { i18n } from '@kbn/i18n'; const theme$ = new BehaviorSubject({ darkMode: false, name: 'amsterdam' }); +const userProfile = { getUserProfile$: () => of(null) }; const i18nStart: I18nStart = { Context: ({ children }) => {children}, @@ -47,7 +48,7 @@ const KibanaContextDecorator: DecoratorFn = (storyFn, { globals }) => { }, [colorMode]); return ( - + {storyFn()} ); diff --git a/packages/react/kibana_context/root/eui_provider.test.tsx b/packages/react/kibana_context/root/eui_provider.test.tsx index d7486be2d4798..11d83f0affc41 100644 --- a/packages/react/kibana_context/root/eui_provider.test.tsx +++ b/packages/react/kibana_context/root/eui_provider.test.tsx @@ -7,24 +7,28 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { useEuiTheme } from '@elastic/eui'; import type { ReactWrapper } from 'enzyme'; import type { FC } from 'react'; import React, { useEffect } from 'react'; import { act } from 'react-dom/test-utils'; import { BehaviorSubject, of } from 'rxjs'; +import { useEuiTheme } from '@elastic/eui'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; +import type { KibanaTheme } from '@kbn/react-kibana-context-common'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import type { KibanaTheme } from '@kbn/react-kibana-context-common'; import { KibanaEuiProvider } from './eui_provider'; describe('KibanaEuiProvider', () => { let euiTheme: ReturnType | undefined; + let userProfile: UserProfileService; let consoleWarnMock: jest.SpyInstance; beforeEach(() => { euiTheme = undefined; + userProfile = userProfileServiceMock.createStart(); consoleWarnMock = jest.spyOn(global.console, 'warn').mockImplementation(() => {}); }); @@ -57,7 +61,11 @@ describe('KibanaEuiProvider', () => { const coreTheme: KibanaTheme = { darkMode: true, name: 'amsterdam' }; const wrapper = mountWithIntl( - + ); @@ -73,7 +81,7 @@ describe('KibanaEuiProvider', () => { const coreTheme$ = new BehaviorSubject({ darkMode: true, name: 'amsterdam' }); const wrapper = mountWithIntl( - + ); diff --git a/packages/react/kibana_context/root/eui_provider.tsx b/packages/react/kibana_context/root/eui_provider.tsx index 1e4e45c9f36f1..fa1d92e897800 100644 --- a/packages/react/kibana_context/root/eui_provider.tsx +++ b/packages/react/kibana_context/root/eui_provider.tsx @@ -19,13 +19,15 @@ import { getThemeConfigByName, DEFAULT_THEME_CONFIG, } from '@kbn/react-kibana-context-common'; -import { ThemeServiceStart } from '@kbn/react-kibana-context-common'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; +import type { ThemeServiceStart } from '@kbn/react-kibana-context-common'; /** * Props for the KibanaEuiProvider. */ export interface KibanaEuiProviderProps extends Pick, 'modify' | 'colorMode'> { theme: ThemeServiceStart; + userProfile?: Pick; // TODO: use this to access a "high contrast mode" flag from user settings. Pass the flag to EuiProvider, when it is supported in EUI. globalStyles?: boolean; } @@ -87,7 +89,14 @@ export const KibanaEuiProvider: FC> = return ( {children} diff --git a/packages/react/kibana_context/root/root_provider.test.tsx b/packages/react/kibana_context/root/root_provider.test.tsx index 919adb09581d5..312b366797a36 100644 --- a/packages/react/kibana_context/root/root_provider.test.tsx +++ b/packages/react/kibana_context/root/root_provider.test.tsx @@ -18,18 +18,22 @@ import type { KibanaTheme } from '@kbn/react-kibana-context-common'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; -import { KibanaRootContextProvider } from './root_provider'; import { I18nStart } from '@kbn/core-i18n-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; +import { KibanaRootContextProvider } from './root_provider'; describe('KibanaRootContextProvider', () => { let euiTheme: UseEuiTheme | undefined; let i18nMock: I18nStart; let analytics: AnalyticsServiceStart; + let userProfile: UserProfileService; beforeEach(() => { euiTheme = undefined; analytics = analyticsServiceMock.createAnalyticsServiceStart(); i18nMock = i18nServiceMock.createStartContract(); + userProfile = userProfileServiceMock.createStart(); }); const flushPromises = async () => { @@ -64,6 +68,7 @@ describe('KibanaRootContextProvider', () => { @@ -82,6 +87,7 @@ describe('KibanaRootContextProvider', () => { diff --git a/packages/react/kibana_context/root/tsconfig.json b/packages/react/kibana_context/root/tsconfig.json index 27ea0566f36a7..6c67c97861c11 100644 --- a/packages/react/kibana_context/root/tsconfig.json +++ b/packages/react/kibana_context/root/tsconfig.json @@ -23,5 +23,7 @@ "@kbn/core-base-common", "@kbn/core-analytics-browser", "@kbn/core-analytics-browser-mocks", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks", ] } diff --git a/packages/react/kibana_context/theme/theme_provider.test.tsx b/packages/react/kibana_context/theme/theme_provider.test.tsx index 9889da9a689a3..8023c0cbf7e5f 100644 --- a/packages/react/kibana_context/theme/theme_provider.test.tsx +++ b/packages/react/kibana_context/theme/theme_provider.test.tsx @@ -16,14 +16,19 @@ import { BehaviorSubject } from 'rxjs'; import { mountWithIntl } from '@kbn/test-jest-helpers'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; + import type { KibanaTheme } from '@kbn/react-kibana-context-common'; import { KibanaThemeProvider } from './theme_provider'; describe('KibanaThemeProvider', () => { let euiTheme: ReturnType | undefined; + let userProfile: UserProfileService; beforeEach(() => { euiTheme = undefined; + userProfile = userProfileServiceMock.createStart(); }); const flushPromises = async () => { @@ -55,7 +60,7 @@ describe('KibanaThemeProvider', () => { const coreTheme$ = new BehaviorSubject({ darkMode: true, name: 'amsterdam' }); const wrapper = mountWithIntl( - + ); @@ -72,7 +77,7 @@ describe('KibanaThemeProvider', () => { }); const wrapper = mountWithIntl( - + ); diff --git a/packages/react/kibana_context/theme/theme_provider.tsx b/packages/react/kibana_context/theme/theme_provider.tsx index 41915824b128a..b962687199ea7 100644 --- a/packages/react/kibana_context/theme/theme_provider.tsx +++ b/packages/react/kibana_context/theme/theme_provider.tsx @@ -17,6 +17,7 @@ import { useIsNestedEuiProvider } from '@elastic/eui/lib/components/provider/nes // @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types import { emitEuiProviderWarning } from '@elastic/eui/lib/services/theme/warning'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { KibanaEuiProvider } from '@kbn/react-kibana-context-root'; import { @@ -40,6 +41,8 @@ interface EuiProps extends Omit, 'theme' | 'col export interface KibanaThemeProviderProps extends EuiProps { /** The `ThemeServiceStart` API. */ theme: ThemeServiceStart; + /** The `UserProfileService` start API. */ + userProfile?: Pick; } /** @@ -70,12 +73,17 @@ const KibanaThemeProviderOnly = ({ * TODO: clintandrewhall - We can remove this and revert to only exporting the above component * once all out-of-band renders are using `KibanaRenderContextProvider`. */ -const KibanaThemeProviderCheck = ({ theme, children, ...props }: KibanaThemeProviderProps) => { +const KibanaThemeProviderCheck = ({ + theme, + userProfile, + children, + ...props +}: KibanaThemeProviderProps) => { const hasEuiProvider = useIsNestedEuiProvider(); if (hasEuiProvider) { return ( - + {children} ); @@ -84,7 +92,7 @@ const KibanaThemeProviderCheck = ({ theme, children, ...props }: KibanaThemeProv 'KibanaThemeProvider requires a parent KibanaRenderContextProvider. Check your React tree and ensure that they are wrapped in a KibanaRenderContextProvider.' ); return ( - + {children} ); diff --git a/packages/react/kibana_context/theme/tsconfig.json b/packages/react/kibana_context/theme/tsconfig.json index 491ef1a5c09f8..cfc672666e4c0 100644 --- a/packages/react/kibana_context/theme/tsconfig.json +++ b/packages/react/kibana_context/theme/tsconfig.json @@ -19,5 +19,7 @@ "@kbn/test-jest-helpers", "@kbn/react-kibana-context-common", "@kbn/react-kibana-context-root", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks", ] } diff --git a/packages/react/kibana_context/theme/with_theme.tsx b/packages/react/kibana_context/theme/with_theme.tsx index 226b3c04c638b..3cffe8ddd1b21 100644 --- a/packages/react/kibana_context/theme/with_theme.tsx +++ b/packages/react/kibana_context/theme/with_theme.tsx @@ -8,6 +8,7 @@ */ import { ThemeServiceStart } from '@kbn/react-kibana-context-common'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import React from 'react'; import { KibanaThemeProvider } from './theme_provider'; @@ -17,6 +18,8 @@ import { KibanaThemeProvider } from './theme_provider'; * @param node The node to wrap. * @param theme The `ThemeServiceStart` API. */ -export const wrapWithTheme = (node: React.ReactNode, theme: ThemeServiceStart) => ( - {node} -); +export const wrapWithTheme = ( + node: React.ReactNode, + theme: ThemeServiceStart, + userProfile?: UserProfileService +) => {node}; diff --git a/packages/react/kibana_mount/to_mount_point.test.tsx b/packages/react/kibana_mount/to_mount_point.test.tsx index 50a49263e2532..5dafefa8453ef 100644 --- a/packages/react/kibana_mount/to_mount_point.test.tsx +++ b/packages/react/kibana_mount/to_mount_point.test.tsx @@ -15,12 +15,14 @@ import type { UseEuiTheme } from '@elastic/eui'; import type { CoreTheme } from '@kbn/core/public'; import { toMountPoint } from './to_mount_point'; import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; describe('toMountPoint', () => { let euiTheme: UseEuiTheme; const i18n = i18nServiceMock.createStartContract(); const analytics = analyticsServiceMock.createAnalyticsServiceStart(); + const userProfile = userProfileServiceMock.createStart(); const InnerComponent: FC = () => { const theme = useEuiTheme(); @@ -42,7 +44,7 @@ describe('toMountPoint', () => { it('exposes the euiTheme when `theme$` is provided', async () => { const theme = { theme$: of({ darkMode: true, name: 'amsterdam' }) }; - const mount = toMountPoint(, { theme, i18n, analytics }); + const mount = toMountPoint(, { theme, i18n, analytics, userProfile }); const targetEl = document.createElement('div'); mount(targetEl); @@ -55,7 +57,12 @@ describe('toMountPoint', () => { it('propagates changes of the theme$ observable', async () => { const theme$ = new BehaviorSubject({ darkMode: true, name: 'amsterdam' }); - const mount = toMountPoint(, { theme: { theme$ }, i18n, analytics }); + const mount = toMountPoint(, { + theme: { theme$ }, + i18n, + analytics, + userProfile, + }); const targetEl = document.createElement('div'); mount(targetEl); diff --git a/packages/react/kibana_mount/to_mount_point.tsx b/packages/react/kibana_mount/to_mount_point.tsx index 45a2f788c850d..8968decee726a 100644 --- a/packages/react/kibana_mount/to_mount_point.tsx +++ b/packages/react/kibana_mount/to_mount_point.tsx @@ -17,7 +17,7 @@ import { export type ToMountPointParams = Pick< KibanaRenderContextProviderProps, - 'analytics' | 'i18n' | 'theme' + 'analytics' | 'i18n' | 'theme' | 'userProfile' >; /** diff --git a/packages/react/kibana_mount/tsconfig.json b/packages/react/kibana_mount/tsconfig.json index 36036d379b7e1..8294fad813c28 100644 --- a/packages/react/kibana_mount/tsconfig.json +++ b/packages/react/kibana_mount/tsconfig.json @@ -21,5 +21,6 @@ "@kbn/core-i18n-browser-mocks", "@kbn/react-kibana-context-render", "@kbn/core-analytics-browser-mocks", + "@kbn/core-user-profile-browser-mocks", ] } diff --git a/src/plugins/home/public/application/application.tsx b/src/plugins/home/public/application/application.tsx index a8459279080bc..b45ab670954e0 100644 --- a/src/plugins/home/public/application/application.tsx +++ b/src/plugins/home/public/application/application.tsx @@ -44,7 +44,7 @@ export const renderApp = async ( ); render( - + & +export type KibanaThemeProviderProps = Pick< + KbnThemeProviderProps, + 'children' | 'modify' | 'userProfile' +> & KbnThemeProviderProps['theme']; /** @deprecated Use `KibanaThemeProvider` from `@kbn/react-kibana-context-theme` */ -export const KibanaThemeProvider = ({ children, theme$, modify }: KibanaThemeProviderProps) => ( - +export const KibanaThemeProvider = ({ + children, + theme$, + userProfile, + modify, +}: KibanaThemeProviderProps) => ( + {children} ); type Theme = KbnThemeProviderProps['theme']['theme$']; -export const wrapWithTheme = (node: React.ReactNode, theme$: Theme) => - kbnWrapWithTheme(node, { theme$ }); +/** @deprecated Use `wrapWithTheme` from `@kbn/react-kibana-context-theme` */ +export const wrapWithTheme = ( + node: React.ReactNode, + theme$: Theme, + userProfile?: UserProfileService +) => kbnWrapWithTheme(node, { theme$ }, userProfile); diff --git a/src/plugins/kibana_react/public/util/index.tsx b/src/plugins/kibana_react/public/util/index.tsx index f58affa049dc5..963dba824a0c4 100644 --- a/src/plugins/kibana_react/public/util/index.tsx +++ b/src/plugins/kibana_react/public/util/index.tsx @@ -15,6 +15,7 @@ import type { MountPoint } from '@kbn/core/public'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { CoreTheme, ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { defaultTheme } from '@kbn/react-kibana-context-common'; import { toMountPoint as _toMountPoint } from '@kbn/react-kibana-mount'; @@ -40,6 +41,7 @@ const i18n: I18nStart = { export interface ToMountPointOptions { analytics?: AnalyticsServiceStart; theme$?: Observable; + userProfile?: UserProfileService; } /** @@ -47,8 +49,8 @@ export interface ToMountPointOptions { */ export const toMountPoint = ( node: React.ReactNode, - { analytics, theme$ }: ToMountPointOptions = {} + { analytics, theme$, userProfile }: ToMountPointOptions = {} ): MountPoint => { const theme = theme$ ? { theme$ } : themeStart; - return _toMountPoint(node, { analytics, theme, i18n }); + return _toMountPoint(node, { analytics, theme, i18n, userProfile }); }; diff --git a/src/plugins/kibana_react/tsconfig.json b/src/plugins/kibana_react/tsconfig.json index cff9a2ce19312..2394c7bfe5250 100644 --- a/src/plugins/kibana_react/tsconfig.json +++ b/src/plugins/kibana_react/tsconfig.json @@ -25,6 +25,7 @@ "@kbn/code-editor", "@kbn/core-analytics-browser", "@kbn/shared-ux-link-redirect-app", + "@kbn/core-user-profile-browser", ], "exclude": [ "target/**/*", diff --git a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx index 89619fc287046..becfb9d0da404 100644 --- a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx +++ b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx @@ -15,6 +15,7 @@ import ReactDOM from 'react-dom'; import { ApplicationStart, HttpStart, ToastsSetup } from '@kbn/core/public'; import type { ThemeServiceStart } from '@kbn/core/public'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { SavedObjectNotFound } from '..'; import { KibanaThemeProvider } from '../theme'; @@ -49,6 +50,7 @@ export function redirectWhenMissing({ toastNotifications, onBeforeRedirect, theme, + userProfile, }: { history: History; navigateToApp: ApplicationStart['navigateToApp']; @@ -67,6 +69,7 @@ export function redirectWhenMissing({ */ onBeforeRedirect?: (error: SavedObjectNotFound) => void; theme: ThemeServiceStart; + userProfile?: UserProfileService; }) { let localMappingObject: Mapping; @@ -98,7 +101,7 @@ export function redirectWhenMissing({ }), text: (element: HTMLElement) => { ReactDOM.render( - + {error.message} , element diff --git a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx index 93511354b19ad..c3c2be931d411 100644 --- a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx +++ b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx @@ -14,6 +14,7 @@ import React, { useEffect } from 'react'; import { act } from 'react-dom/test-utils'; import { BehaviorSubject, of } from 'rxjs'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import type { CoreTheme } from '@kbn/core/public'; @@ -21,6 +22,7 @@ import { KibanaThemeProvider } from './kibana_theme_provider'; describe('KibanaThemeProvider', () => { let euiTheme: ReturnType | undefined; + const userProfile = userProfileServiceMock.createStart(); beforeEach(() => { euiTheme = undefined; @@ -55,7 +57,7 @@ describe('KibanaThemeProvider', () => { const coreTheme: CoreTheme = { darkMode: true, name: 'amsterdam' }; const wrapper = mountWithIntl( - + ); @@ -69,7 +71,7 @@ describe('KibanaThemeProvider', () => { const coreTheme$ = new BehaviorSubject({ darkMode: true, name: 'amsterdam' }); const wrapper = mountWithIntl( - + ); diff --git a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx index bc104836e2780..3550a34781da2 100644 --- a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx +++ b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx @@ -12,10 +12,12 @@ import { Observable } from 'rxjs'; import { EuiProviderProps } from '@elastic/eui'; import { CoreTheme } from '@kbn/core-theme-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import { KibanaThemeProvider as KbnThemeProvider } from '@kbn/react-kibana-context-theme'; export interface KibanaThemeProviderProps { theme$: Observable; + userProfile?: UserProfileService; modify?: EuiProviderProps<{}>['modify']; children: React.ReactNode; } @@ -23,6 +25,11 @@ export interface KibanaThemeProviderProps { /** @deprecated use `KibanaThemeProvider` from `@kbn/react-kibana-context-theme */ export const KibanaThemeProvider: FC> = ({ theme$, + userProfile, modify, children, -}) => {children}; +}) => ( + + {children} + +); diff --git a/src/plugins/kibana_utils/tsconfig.json b/src/plugins/kibana_utils/tsconfig.json index ceb0d705d5780..0b45dc44ed994 100644 --- a/src/plugins/kibana_utils/tsconfig.json +++ b/src/plugins/kibana_utils/tsconfig.json @@ -23,6 +23,8 @@ "@kbn/core-notifications-browser-mocks", "@kbn/react-kibana-context-theme", "@kbn/core-theme-browser", + "@kbn/core-user-profile-browser", + "@kbn/core-user-profile-browser-mocks", ], "exclude": [ "target/**/*", diff --git a/src/plugins/saved_objects/public/kibana_services.ts b/src/plugins/saved_objects/public/kibana_services.ts index 60c4eb9da457b..8c37ef8b6e046 100644 --- a/src/plugins/saved_objects/public/kibana_services.ts +++ b/src/plugins/saved_objects/public/kibana_services.ts @@ -17,3 +17,4 @@ export function setStartServices(core: CoreStart) { export const getAnalytics = () => coreStart.analytics; export const getI18n = () => coreStart.i18n; export const getTheme = () => coreStart.theme; +export const getUserProfile = () => coreStart.userProfile; diff --git a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx index 70ab2a39b7bfb..85b4ce3a5d03b 100644 --- a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx @@ -10,7 +10,7 @@ import React, { FC, PropsWithChildren } from 'react'; import { toMountPoint } from '@kbn/react-kibana-mount'; -import { getAnalytics, getI18n, getTheme } from '../kibana_services'; +import { getAnalytics, getI18n, getTheme, getUserProfile } from '../kibana_services'; /** * Represents the result of trying to persist the saved object. @@ -68,7 +68,7 @@ export function showSaveModal( children: augmentedElement, }); }), - { analytics: getAnalytics(), theme: getTheme(), i18n: getI18n() } + { analytics: getAnalytics(), theme: getTheme(), i18n: getI18n(), userProfile: getUserProfile() } ); unmount = mount(document.createElement('div')); diff --git a/src/plugins/saved_objects/public/types.ts b/src/plugins/saved_objects/public/types.ts index 0919c24ab2c62..4a8ac83921266 100644 --- a/src/plugins/saved_objects/public/types.ts +++ b/src/plugins/saved_objects/public/types.ts @@ -54,7 +54,7 @@ export interface SavedObjectCreationOpts { overwrite?: boolean; } -export type StartServices = Pick; +export type StartServices = Pick; export interface SavedObjectAttributesAndRefs { attributes: SavedObjectAttributes; diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx index e5d838691f66c..14644d7664bfd 100644 --- a/src/plugins/share/public/services/share_menu_manager.tsx +++ b/src/plugins/share/public/services/share_menu_manager.tsx @@ -10,7 +10,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { toMountPoint } from '@kbn/react-kibana-mount'; -import { CoreStart, ThemeServiceStart, ToastsSetup } from '@kbn/core/public'; +import { CoreStart, ThemeServiceStart, ToastsSetup, UserProfileService } from '@kbn/core/public'; import { ShowShareMenuOptions } from '../types'; import { ShareMenuRegistryStart } from './share_menu_registry'; import { AnonymousAccessServiceContract } from '../../common/anonymous_access'; @@ -49,10 +49,9 @@ export class ShareMenuManager { menuItems, urlService, anonymousAccess, - theme: core.theme, - i18n: core.i18n, toasts: core.notifications.toasts, publicAPIEnabled: !disableEmbed, + ...core, }); }, }; @@ -75,28 +74,28 @@ export class ShareMenuManager { shareableUrl, shareableUrlLocatorParams, embedUrlParamExtensions, - theme, showPublicUrlSwitch, urlService, anonymousAccess, snapshotShareWarning, onClose, disabledShareUrl, - i18n, isDirty, toasts, delegatedShareUrlHandler, publicAPIEnabled, + ...startServices }: ShowShareMenuOptions & { anchorElement: HTMLElement; menuItems: ShareMenuItemV2[]; urlService: BrowserUrlService; anonymousAccess: AnonymousAccessServiceContract | undefined; - theme: ThemeServiceStart; onClose: () => void; - i18n: CoreStart['i18n']; isDirty: boolean; toasts: ToastsSetup; + userProfile: UserProfileService; + theme: ThemeServiceStart; + i18n: CoreStart['i18n']; }) { if (this.isOpen) { onClose(); @@ -135,11 +134,10 @@ export class ShareMenuManager { onClose(); unmount(); }, - theme, - i18n, + ...startServices, }} />, - { i18n, theme } + startServices ); const openModal = () => { diff --git a/src/plugins/share/public/url_service/redirect/components/page.tsx b/src/plugins/share/public/url_service/redirect/components/page.tsx index d2722a1976038..c5f2a93450092 100644 --- a/src/plugins/share/public/url_service/redirect/components/page.tsx +++ b/src/plugins/share/public/url_service/redirect/components/page.tsx @@ -14,6 +14,7 @@ import { EuiPageTemplate } from '@elastic/eui'; import type { CustomBrandingSetup } from '@kbn/core-custom-branding-browser'; import type { ChromeDocTitle, ThemeServiceSetup } from '@kbn/core/public'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { RedirectManager } from '../redirect_manager'; import { RedirectEmptyPrompt } from './empty_prompt'; @@ -25,6 +26,7 @@ export interface PageProps { customBranding: CustomBrandingSetup; manager: Pick; theme: ThemeServiceSetup; + userProfile: UserProfileService; } export const Page: React.FC = ({ @@ -32,14 +34,14 @@ export const Page: React.FC = ({ homeHref, customBranding, docTitle, - theme, + ...startServices }) => { const error = useObservable(manager.error$); const hasCustomBranding = useObservable(customBranding.hasCustomBranding$); if (error) { return ( - + @@ -48,7 +50,7 @@ export const Page: React.FC = ({ } return ( - + diff --git a/src/plugins/share/public/url_service/redirect/redirect_manager.ts b/src/plugins/share/public/url_service/redirect/redirect_manager.ts index 18d909808ef3c..c4dd843deed00 100644 --- a/src/plugins/share/public/url_service/redirect/redirect_manager.ts +++ b/src/plugins/share/public/url_service/redirect/redirect_manager.ts @@ -39,13 +39,14 @@ export class RedirectManager { mount: async (params) => { const { render } = await import('./render'); const [start] = await core.getStartServices(); - const { chrome, uiSettings } = start; + const { chrome, uiSettings, userProfile } = start; const unmount = render(params.element, { manager: this, customBranding, docTitle: chrome.docTitle, theme, + userProfile, homeHref: getHomeHref(http, uiSettings), }); diff --git a/src/plugins/share/tsconfig.json b/src/plugins/share/tsconfig.json index 8bc8474a84eef..acd84ebc97a83 100644 --- a/src/plugins/share/tsconfig.json +++ b/src/plugins/share/tsconfig.json @@ -25,6 +25,7 @@ "@kbn/core-theme-browser-mocks", "@kbn/core-i18n-browser-mocks", "@kbn/core-notifications-browser-mocks", + "@kbn/core-user-profile-browser", ], "exclude": [ "target/**/*", diff --git a/src/plugins/telemetry/public/mocks.ts b/src/plugins/telemetry/public/mocks.ts index 6461c2e154e88..ad7926cc4211f 100644 --- a/src/plugins/telemetry/public/mocks.ts +++ b/src/plugins/telemetry/public/mocks.ts @@ -15,6 +15,7 @@ import { notificationServiceMock, themeServiceMock, } from '@kbn/core/public/mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import type { TelemetryConstants } from '.'; import type { TelemetryPluginStart, TelemetryPluginSetup, TelemetryPluginConfig } from './plugin'; import { TelemetryService, TelemetryNotifications } from './services'; @@ -82,6 +83,7 @@ export function mockTelemetryNotifications({ analytics: analyticsServiceMock.createAnalyticsServiceStart(), i18n: i18nServiceMock.createStartContract(), theme: themeServiceMock.createStartContract(), + userProfile: userProfileServiceMock.createStart(), telemetryService, telemetryConstants: mockTelemetryConstants(), }); diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.test.ts b/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.test.ts index 6f2d29371df65..8eedf9fc02b67 100644 --- a/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.test.ts @@ -15,6 +15,7 @@ import { overlayServiceMock, themeServiceMock, } from '@kbn/core/public/mocks'; +import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks'; import { mockTelemetryConstants, mockTelemetryService } from '../../mocks'; describe('renderOptInStatusNoticeBanner', () => { @@ -25,6 +26,7 @@ describe('renderOptInStatusNoticeBanner', () => { const analytics = analyticsServiceMock.createAnalyticsServiceStart(); const i18n = i18nServiceMock.createStartContract(); const theme = themeServiceMock.createStartContract(); + const userProfile = userProfileServiceMock.createStart(); const telemetryConstants = mockTelemetryConstants(); const telemetryService = mockTelemetryService(); overlays.banners.add.mockReturnValue(bannerID); @@ -36,6 +38,7 @@ describe('renderOptInStatusNoticeBanner', () => { analytics, i18n, theme, + userProfile, telemetryConstants, telemetryService, }); diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.tsx b/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.tsx index 4227319b0f65a..4d54de430e954 100644 --- a/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.tsx +++ b/src/plugins/telemetry/public/services/telemetry_notifications/render_opt_in_status_notice_banner.tsx @@ -14,7 +14,8 @@ import { withSuspense } from '@kbn/shared-ux-utility'; import { TelemetryService } from '..'; import type { TelemetryConstants } from '../..'; -interface RenderBannerConfig extends Pick { +interface RenderBannerConfig + extends Pick { http: HttpStart; overlays: OverlayStart; onSeen: () => void; diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts index b830ef6872df8..99195f9b32589 100644 --- a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts +++ b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts @@ -12,8 +12,9 @@ import type { TelemetryService } from '../telemetry_service'; import type { TelemetryConstants } from '../..'; import { renderOptInStatusNoticeBanner } from './render_opt_in_status_notice_banner'; -interface TelemetryNotificationsConstructor - extends Pick { +type StartServices = Pick; + +interface TelemetryNotificationsConstructor extends StartServices { http: HttpStart; overlays: OverlayStart; telemetryService: TelemetryService; @@ -26,7 +27,7 @@ interface TelemetryNotificationsConstructor export class TelemetryNotifications { private readonly http: HttpStart; private readonly overlays: OverlayStart; - private readonly startServices: Pick; + private readonly startServices: StartServices; private readonly telemetryConstants: TelemetryConstants; private readonly telemetryService: TelemetryService; private optInStatusNoticeBannerId?: string; diff --git a/src/plugins/telemetry/tsconfig.json b/src/plugins/telemetry/tsconfig.json index c23b4fea26b89..68a9e0118e0fc 100644 --- a/src/plugins/telemetry/tsconfig.json +++ b/src/plugins/telemetry/tsconfig.json @@ -35,6 +35,7 @@ "@kbn/react-kibana-mount", "@kbn/core-node-server", "@kbn/security-plugin-types-server", + "@kbn/core-user-profile-browser-mocks", ], "exclude": [ "target/**/*", diff --git a/src/plugins/ui_actions/public/context_menu/open_context_menu.tsx b/src/plugins/ui_actions/public/context_menu/open_context_menu.tsx index ab8a12374a605..1321ad9fd3803 100644 --- a/src/plugins/ui_actions/public/context_menu/open_context_menu.tsx +++ b/src/plugins/ui_actions/public/context_menu/open_context_menu.tsx @@ -13,7 +13,7 @@ import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiPopover } from '@elas import { EventEmitter } from 'events'; import ReactDOM from 'react-dom'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; -import { getAnalytics, getI18n, getTheme } from '../services'; +import { getAnalytics, getI18n, getTheme, getUserProfile } from '../services'; let activeSession: ContextMenuSession | null = null; @@ -171,7 +171,12 @@ export function openContextMenu( }; ReactDOM.render( - + | undefined' diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts index 988ef1116e715..4ffea25313b29 100644 --- a/src/plugins/ui_actions/public/plugin.ts +++ b/src/plugins/ui_actions/public/plugin.ts @@ -16,7 +16,7 @@ import { addPanelMenuTrigger, } from '@kbn/ui-actions-browser/src/triggers'; import { UiActionsService } from './service'; -import { setAnalytics, setI18n, setNotifications, setTheme } from './services'; +import { setAnalytics, setI18n, setNotifications, setTheme, setUserProfile } from './services'; export type UiActionsPublicSetup = Pick< UiActionsService, @@ -62,6 +62,7 @@ export class UiActionsPlugin setI18n(core.i18n); setNotifications(core.notifications); setTheme(core.theme); + setUserProfile(core.userProfile); return this.service; } diff --git a/src/plugins/ui_actions/public/services.ts b/src/plugins/ui_actions/public/services.ts index ccb9520c3bcfb..981d3c9c78976 100644 --- a/src/plugins/ui_actions/public/services.ts +++ b/src/plugins/ui_actions/public/services.ts @@ -7,7 +7,13 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { AnalyticsServiceStart, CoreStart, I18nStart, ThemeServiceSetup } from '@kbn/core/public'; +import { + AnalyticsServiceStart, + CoreStart, + I18nStart, + ThemeServiceSetup, + UserProfileService, +} from '@kbn/core/public'; import { createGetterSetter } from '@kbn/kibana-utils-plugin/public'; export const [getAnalytics, setAnalytics] = createGetterSetter('Analytics'); @@ -15,3 +21,5 @@ export const [getI18n, setI18n] = createGetterSetter('I18n'); export const [getNotifications, setNotifications] = createGetterSetter('Notifications'); export const [getTheme, setTheme] = createGetterSetter('Theme'); +export const [getUserProfile, setUserProfile] = + createGetterSetter('UserProfile'); diff --git a/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx b/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx index 25296929e10fd..aa087eb524b46 100644 --- a/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx +++ b/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx @@ -14,7 +14,7 @@ import { toMountPoint } from '@kbn/react-kibana-mount'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { ActionDefinition } from '../../actions'; -type StartServices = Pick; +type StartServices = Pick; const getMenuItem = (core: StartServices) => { return () => { diff --git a/test/plugin_functional/plugins/core_plugin_helpmenu/public/application.tsx b/test/plugin_functional/plugins/core_plugin_helpmenu/public/application.tsx index f3d64605f1fc3..a2f48362ebe7d 100644 --- a/test/plugin_functional/plugins/core_plugin_helpmenu/public/application.tsx +++ b/test/plugin_functional/plugins/core_plugin_helpmenu/public/application.tsx @@ -18,6 +18,7 @@ import { EuiTitle, } from '@elastic/eui'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; +import type { UserProfileService } from '@kbn/core-user-profile-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; @@ -26,6 +27,7 @@ interface StartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } import { AppMountParameters } from '@kbn/core/public'; diff --git a/test/plugin_functional/plugins/core_plugin_helpmenu/tsconfig.json b/test/plugin_functional/plugins/core_plugin_helpmenu/tsconfig.json index de2437f09fa9b..fd21ffba5d3d6 100644 --- a/test/plugin_functional/plugins/core_plugin_helpmenu/tsconfig.json +++ b/test/plugin_functional/plugins/core_plugin_helpmenu/tsconfig.json @@ -17,6 +17,7 @@ "@kbn/core-analytics-browser", "@kbn/core-i18n-browser", "@kbn/core-theme-browser", - "@kbn/react-kibana-context-render" + "@kbn/react-kibana-context-render", + "@kbn/core-user-profile-browser" ] } diff --git a/x-pack/examples/screenshotting_example/public/app/http_context.ts b/x-pack/examples/screenshotting_example/public/app/http_context.ts index 7bc0b2b4f2870..1c3b6c164440c 100644 --- a/x-pack/examples/screenshotting_example/public/app/http_context.ts +++ b/x-pack/examples/screenshotting_example/public/app/http_context.ts @@ -11,6 +11,7 @@ import type { HttpStart, I18nStart, ThemeServiceStart, + UserProfileService, } from '@kbn/core/public'; export interface StartServices { @@ -18,6 +19,7 @@ export interface StartServices { analytics: Pick; i18n: I18nStart; theme: Pick; + userProfile: UserProfileService; } export const AppContext = createContext(undefined); diff --git a/x-pack/examples/screenshotting_example/public/plugin.tsx b/x-pack/examples/screenshotting_example/public/plugin.tsx index 6dd07b992b1c3..b020424cc5d76 100644 --- a/x-pack/examples/screenshotting_example/public/plugin.tsx +++ b/x-pack/examples/screenshotting_example/public/plugin.tsx @@ -26,8 +26,8 @@ export class ScreenshottingExamplePlugin implements Plugin { title: APPLICATION_NAME, visibleIn: [], mount: async ({ element }: AppMountParameters) => { - const [{ http, analytics, i18n, theme }] = await getStartServices(); - const startServices = { analytics, http, i18n, theme }; + const [{ http, analytics, i18n, theme, userProfile }] = await getStartServices(); + const startServices = { analytics, http, i18n, theme, userProfile }; ReactDOM.render( diff --git a/x-pack/plugins/global_search_bar/public/plugin.tsx b/x-pack/plugins/global_search_bar/public/plugin.tsx index e8fbe2f7e2bf1..4ff393b90f044 100644 --- a/x-pack/plugins/global_search_bar/public/plugin.tsx +++ b/x-pack/plugins/global_search_bar/public/plugin.tsx @@ -50,14 +50,14 @@ export class GlobalSearchBarPlugin implements Plugin<{}, {}, {}, GlobalSearchBar private getNavControl(deps: { core: CoreStart } & GlobalSearchBarPluginStartDeps) { const { core, globalSearch, savedObjectsTagging, usageCollection } = deps; - const { application, http, theme, i18n } = core; + const { application, http } = core; const reportEvent = new EventReporter({ analytics: core.analytics, usageCollection }); const navControl: ChromeNavControl = { order: 1000, mount: (container) => { ReactDOM.render( - + = (props) => ( ); -type MountProps = Props & Pick; +type MountProps = Props & Pick; export const mountExpiredBanner = ({ type, uploadUrl, ...startServices }: MountProps) => toMountPoint(, startServices); diff --git a/x-pack/plugins/reporting/public/plugin.ts b/x-pack/plugins/reporting/public/plugin.ts index 8dc9e2d96f717..d1c0db9cca577 100644 --- a/x-pack/plugins/reporting/public/plugin.ts +++ b/x-pack/plugins/reporting/public/plugin.ts @@ -110,15 +110,16 @@ export class ReportingPublicPlugin } = setupDeps; const startServices$: Observable = from(getStartServices()).pipe( - map(([services, ...rest]) => { + map(([start, ...rest]) => { return [ { - application: services.application, - analytics: services.analytics, - i18n: services.i18n, - theme: services.theme, - notifications: services.notifications, - uiSettings: services.uiSettings, + application: start.application, + analytics: start.analytics, + i18n: start.i18n, + theme: start.theme, + userProfile: start.userProfile, + notifications: start.notifications, + uiSettings: start.uiSettings, }, ...rest, ]; diff --git a/x-pack/plugins/reporting/public/types.ts b/x-pack/plugins/reporting/public/types.ts index 9ba50435471ab..c4b9b5e931c53 100644 --- a/x-pack/plugins/reporting/public/types.ts +++ b/x-pack/plugins/reporting/public/types.ts @@ -20,6 +20,7 @@ export type StartServices = [ | 'analytics' | 'i18n' | 'theme' + | 'userProfile' // used extensively in Reporting plugin | 'application' | 'notifications' diff --git a/x-pack/plugins/saved_objects_tagging/public/types.ts b/x-pack/plugins/saved_objects_tagging/public/types.ts index ed29542e4d410..7211dd205c53b 100644 --- a/x-pack/plugins/saved_objects_tagging/public/types.ts +++ b/x-pack/plugins/saved_objects_tagging/public/types.ts @@ -12,5 +12,5 @@ export type SavedObjectTaggingPluginStart = SavedObjectsTaggingApi; export type StartServices = Pick< CoreStart, - 'overlays' | 'notifications' | 'analytics' | 'i18n' | 'theme' + 'overlays' | 'notifications' | 'analytics' | 'i18n' | 'theme' | 'userProfile' >; diff --git a/x-pack/plugins/serverless/public/plugin.tsx b/x-pack/plugins/serverless/public/plugin.tsx index dbb75788c105b..a488658e9bb94 100644 --- a/x-pack/plugins/serverless/public/plugin.tsx +++ b/x-pack/plugins/serverless/public/plugin.tsx @@ -83,7 +83,7 @@ export class ServerlessPlugin core.chrome.navControls.registerRight({ order: 1, mount: toMountPoint( - + +