From 6178e8295dc35343ab1847416a6d40432a35e4a5 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Thu, 5 Dec 2024 08:26:41 -0700 Subject: [PATCH] Preparation for High Contrast Mode, Core/SharedUX domains (#202606) ## Summary **Reviewers: Please test the code paths affected by this PR. See the "Risks" section below.** Part of work for enabling "high contrast mode" in Kibana. See https://github.com/elastic/kibana/issues/176219. **Background:** Kibana will soon have a user profile setting to allow users to enable "high contrast mode." This setting will activate a flag with `` that causes EUI components to render with higher contrast visual elements. Consumer plugins and packages need to be updated selected places where `` is wrapped, to pass the `UserProfileService` service dependency from the CoreStart contract. **NOTE:** **EUI currently does not yet support the high-contrast mode flag**, but support for that is expected to come in around 2 weeks. These first PRs are simply preparing the code by wiring up the `UserProvideService`. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [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 - [X] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ### Risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [medium/high] The implementor of this change did not manually test the affected code paths and relied on type-checking and functional tests to drive the changes. Code owners for this PR need to manually test the affected code paths. - [ ] [medium] The `UserProfileService` dependency comes from the CoreStart contract. If acquiring the service causes synchronous code to become asynchronous, check for race conditions or errors in rendering React components. Code owners for this PR need to manually test the affected code paths. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- examples/developer_examples/public/app.tsx | 2 + examples/developer_examples/public/plugin.ts | 4 +- examples/routing_example/public/services.ts | 6 +- .../public/hello_world_action.tsx | 2 +- .../public/hello_world_example.tsx | 2 +- .../cloud/connection_details/kibana/global.ts | 1 + .../kibana/open_connection_details.tsx | 1 + .../content_editor/src/services.tsx | 2 + .../content_editor/tsconfig.json | 1 + .../table_list_view_table/src/services.tsx | 3 +- .../src/core_app.ts | 8 +- .../src/errors/public_base_url.test.tsx | 9 +- .../src/errors/public_base_url.tsx | 2 + .../core-apps-browser-internal/tsconfig.json | 4 +- .../src/chrome_service.test.tsx | 2 + .../tsconfig.json | 1 + .../src/notifications_service.ts | 20 +--- .../__snapshots__/error_toast.test.tsx.snap | 10 ++ .../toasts_service.test.tsx.snap | 10 ++ .../src/toasts/error_toast.test.tsx | 3 + .../src/toasts/error_toast.tsx | 7 +- .../src/toasts/toasts_api.test.ts | 4 + .../src/toasts/toasts_api.tsx | 39 +++---- .../src/toasts/toasts_service.test.tsx | 6 + .../src/toasts/toasts_service.tsx | 8 +- .../tsconfig.json | 4 +- .../src/banners/banners_service.test.ts | 2 + .../src/banners/banners_service.tsx | 2 + .../src/banners/user_banner_service.test.ts | 3 + .../src/banners/user_banner_service.tsx | 2 + .../flyout_service.test.tsx.snap | 30 +++++ .../src/flyout/flyout_service.test.tsx | 3 + .../src/flyout/flyout_service.tsx | 17 ++- .../__snapshots__/modal_service.test.tsx.snap | 110 ++++++++++++++++++ .../src/modal/modal_service.test.tsx | 3 + .../src/modal/modal_service.tsx | 8 +- .../src/overlay_service.ts | 16 ++- .../tsconfig.json | 2 + .../src/rendering_service.test.tsx | 5 +- .../src/rendering_service.tsx | 2 + .../tsconfig.json | 4 +- .../src/core_system.test.ts | 2 + .../src/core_system.ts | 4 + .../src/core_theme_provider.test.tsx | 10 +- .../src/core_theme_provider.tsx | 7 +- .../core-theme-browser-internal/tsconfig.json | 2 + .../src/user_profile_service.mock.ts | 5 +- .../panel_actions/get_csv_panel_action.tsx | 15 +-- .../public/share/share_context_menu/index.ts | 1 + packages/kbn-storybook/src/lib/decorators.tsx | 5 +- .../kibana_context/root/eui_provider.test.tsx | 16 ++- .../kibana_context/root/eui_provider.tsx | 13 ++- .../root/root_provider.test.tsx | 8 +- .../react/kibana_context/root/tsconfig.json | 2 + .../theme/theme_provider.test.tsx | 9 +- .../kibana_context/theme/theme_provider.tsx | 14 ++- .../react/kibana_context/theme/tsconfig.json | 2 + .../react/kibana_context/theme/with_theme.tsx | 9 +- .../kibana_mount/to_mount_point.test.tsx | 11 +- .../react/kibana_mount/to_mount_point.tsx | 2 +- packages/react/kibana_mount/tsconfig.json | 1 + .../home/public/application/application.tsx | 2 +- src/plugins/kibana_react/public/theme.tsx | 23 +++- .../kibana_react/public/util/index.tsx | 6 +- src/plugins/kibana_react/tsconfig.json | 1 + .../public/history/redirect_when_missing.tsx | 5 +- .../theme/kibana_theme_provider.test.tsx | 6 +- .../public/theme/kibana_theme_provider.tsx | 9 +- src/plugins/kibana_utils/tsconfig.json | 2 + .../saved_objects/public/kibana_services.ts | 1 + .../show_saved_object_save_modal.tsx | 4 +- src/plugins/saved_objects/public/types.ts | 2 +- .../public/services/share_menu_manager.tsx | 18 ++- .../url_service/redirect/components/page.tsx | 8 +- .../url_service/redirect/redirect_manager.ts | 3 +- src/plugins/share/tsconfig.json | 1 + src/plugins/telemetry/public/mocks.ts | 2 + ...render_opt_in_status_notice_banner.test.ts | 3 + .../render_opt_in_status_notice_banner.tsx | 3 +- .../telemetry_notifications.ts | 7 +- src/plugins/telemetry/tsconfig.json | 1 + .../public/context_menu/open_context_menu.tsx | 9 +- src/plugins/ui_actions/public/plugin.ts | 3 +- src/plugins/ui_actions/public/services.ts | 10 +- .../tests/test_samples/hello_world_action.tsx | 2 +- .../public/application.tsx | 2 + .../core_plugin_helpmenu/tsconfig.json | 3 +- .../public/app/http_context.ts | 2 + .../screenshotting_example/public/plugin.tsx | 4 +- .../global_search_bar/public/plugin.tsx | 4 +- .../licensing/public/expired_banner.tsx | 2 +- x-pack/plugins/reporting/public/plugin.ts | 15 +-- x-pack/plugins/reporting/public/types.ts | 1 + .../saved_objects_tagging/public/types.ts | 2 +- x-pack/plugins/serverless/public/plugin.tsx | 4 +- 95 files changed, 514 insertions(+), 164 deletions(-) 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( - + +