From 6ca5299b45081a3fcb9a4c898647ab7acf32829d Mon Sep 17 00:00:00 2001
From: shivindera
Date: Wed, 5 Jan 2022 15:30:26 +0100
Subject: [PATCH 1/7] add KibanaThemeProvider to ReactDOM.render for
kibana-app-services
---
.../mount_management_section.tsx | 42 +++++++-------
.../application/main/discover_main_route.tsx | 2 +
src/plugins/embeddable/public/index.ts | 4 ++
.../lib/embeddables/error_embeddable.tsx | 30 +++++-----
src/plugins/embeddable/public/plugin.tsx | 2 +
src/plugins/kibana_utils/kibana.json | 1 +
.../public/history/redirect_when_missing.tsx | 11 +++-
src/plugins/kibana_utils/tsconfig.json | 3 +-
src/plugins/share/kibana.json | 2 +-
.../public/services/share_menu_manager.tsx | 57 +++++++++++--------
.../url_service/redirect/components/page.tsx | 38 ++++++++-----
.../url_service/redirect/redirect_manager.ts | 3 +-
.../public/url_service/redirect/render.ts | 2 +-
src/plugins/share/tsconfig.json | 3 +-
.../public/context_menu/open_context_menu.tsx | 32 ++++++-----
src/plugins/ui_actions/public/index.ts | 4 ++
src/plugins/ui_actions/public/plugin.ts | 2 +
.../public/application/utils/utils.ts | 2 +
src/plugins/visualize/public/plugin.ts | 2 +
src/plugins/visualize/public/services.ts | 4 +-
.../reporting_example/public/application.tsx | 16 ++++--
21 files changed, 162 insertions(+), 100 deletions(-)
diff --git a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
index 6e0e7ffc9091d..eeee5e92b8dee 100644
--- a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
+++ b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
@@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n-react';
import { StartServicesAccessor } from 'src/core/public';
-import { KibanaContextProvider } from '../../../kibana_react/public';
+import { KibanaContextProvider, KibanaThemeProvider } from '../../../kibana_react/public';
import { ManagementAppMountParams } from '../../../management/public';
import {
IndexPatternTableWithRouter,
@@ -67,25 +67,27 @@ export async function mountManagementSection(
ReactDOM.render(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
,
params.element
);
diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx
index b2576a3b5d582..dd1d036b811a2 100644
--- a/src/plugins/discover/public/application/main/discover_main_route.tsx
+++ b/src/plugins/discover/public/application/main/discover_main_route.tsx
@@ -122,6 +122,7 @@ export function DiscoverMainRoute({ services, history }: DiscoverMainProps) {
onBeforeRedirect() {
getUrlTracker().setTrackedUrl('/');
},
+ theme: core.theme,
})(e);
}
}
@@ -139,6 +140,7 @@ export function DiscoverMainRoute({ services, history }: DiscoverMainProps) {
id,
services,
toastNotifications,
+ core.theme,
]);
useEffect(() => {
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index c6beccd5e3365..8cf1269b982a1 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -10,6 +10,8 @@ import './index.scss';
import { PluginInitializerContext } from 'src/core/public';
import { EmbeddablePublicPlugin } from './plugin';
+import type { ThemeServiceStart } from '../../../core/public';
+import { createGetterSetter } from '../../../plugins/kibana_utils/public';
export type {
Adapters,
@@ -83,6 +85,8 @@ export function plugin(initializerContext: PluginInitializerContext) {
return new EmbeddablePublicPlugin(initializerContext);
}
+export const [getTheme, setTheme] = createGetterSetter('Theme');
+
export type {
EmbeddableSetup,
EmbeddableStart,
diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
index f4c650507add9..ab8551500adbf 100644
--- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
@@ -9,10 +9,11 @@
import { EuiText, EuiIcon, EuiSpacer } from '@elastic/eui';
import React from 'react';
import ReactDOM from 'react-dom';
-import { Markdown } from '../../../../kibana_react/public';
+import { KibanaThemeProvider, Markdown } from '../../../../kibana_react/public';
import { Embeddable } from './embeddable';
import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable';
import { IContainer } from '../containers';
+import { getTheme } from '../..';
export const ERROR_EMBEDDABLE_TYPE = 'error';
@@ -38,18 +39,21 @@ export class ErrorEmbeddable extends Embeddable
-
-
-
-
-
- ,
+
+ // @ts-ignore
+
+
+
+
+
+
+
+ ,
+ ,
dom
);
}
diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx
index 465c5d741d5a9..9c9574651ff1d 100644
--- a/src/plugins/embeddable/public/plugin.tsx
+++ b/src/plugins/embeddable/public/plugin.tsx
@@ -52,6 +52,7 @@ import {
getTelemetryFunction,
} from '../common/lib';
import { getAllMigrations } from '../common/lib/get_all_migrations';
+import { setTheme } from '.';
export interface EmbeddableSetupDependencies {
uiActions: UiActionsSetup;
@@ -120,6 +121,7 @@ export class EmbeddablePublicPlugin implements Plugin import('react-markdown'));
const ErrorRenderer = (props: { children: string }) => (
@@ -45,6 +47,7 @@ export function redirectWhenMissing({
mapping,
toastNotifications,
onBeforeRedirect,
+ theme,
}: {
history: History;
navigateToApp: ApplicationStart['navigateToApp'];
@@ -62,6 +65,7 @@ export function redirectWhenMissing({
* Optional callback invoked directly before a redirect is triggered
*/
onBeforeRedirect?: (error: SavedObjectNotFound) => void;
+ theme: ThemeServiceStart;
}) {
let localMappingObject: Mapping;
@@ -92,7 +96,12 @@ export function redirectWhenMissing({
defaultMessage: 'Saved object is missing',
}),
text: (element: HTMLElement) => {
- ReactDOM.render({error.message}, element);
+ ReactDOM.render(
+
+ {error.message}
+ ,
+ element
+ );
return () => ReactDOM.unmountComponentAtNode(element);
},
});
diff --git a/src/plugins/kibana_utils/tsconfig.json b/src/plugins/kibana_utils/tsconfig.json
index 0538b145a5d62..50888e9a7f85b 100644
--- a/src/plugins/kibana_utils/tsconfig.json
+++ b/src/plugins/kibana_utils/tsconfig.json
@@ -15,6 +15,7 @@
"../../../typings/**/*"
],
"references": [
- { "path": "../../core/tsconfig.json" }
+ { "path": "../../core/tsconfig.json" },
+ { "path": "../kibana_react/tsconfig.json" }
]
}
diff --git a/src/plugins/share/kibana.json b/src/plugins/share/kibana.json
index 2e34da1da0287..08365d895f4b4 100644
--- a/src/plugins/share/kibana.json
+++ b/src/plugins/share/kibana.json
@@ -8,6 +8,6 @@
"githubTeam": "kibana-app-services"
},
"description": "Adds URL Service and sharing capabilities to Kibana",
- "requiredBundles": ["kibanaUtils"],
+ "requiredBundles": ["kibanaReact", "kibanaUtils"],
"optionalPlugins": []
}
diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx
index 52f000512aa07..8763c2f3ed87d 100644
--- a/src/plugins/share/public/services/share_menu_manager.tsx
+++ b/src/plugins/share/public/services/share_menu_manager.tsx
@@ -10,8 +10,10 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { I18nProvider } from '@kbn/i18n-react';
import { EuiWrappingPopover } from '@elastic/eui';
+import { Observable } from 'rxjs';
-import { CoreStart, HttpStart } from 'kibana/public';
+import { CoreStart, CoreTheme, HttpStart } from 'kibana/public';
+import { KibanaThemeProvider } from '../../../kibana_react/public';
import { ShareContextMenu } from '../components/share_context_menu';
import { ShareMenuItem, ShowShareMenuOptions } from '../types';
import { ShareMenuRegistryStart } from './share_menu_registry';
@@ -42,6 +44,7 @@ export class ShareMenuManager {
post: core.http.post,
basePath: core.http.basePath.get(),
anonymousAccess,
+ theme$: core.theme.theme$,
});
},
};
@@ -65,12 +68,14 @@ export class ShareMenuManager {
basePath,
embedUrlParamExtensions,
anonymousAccess,
+ theme$,
showPublicUrlSwitch,
}: ShowShareMenuOptions & {
menuItems: ShareMenuItem[];
post: HttpStart['post'];
basePath: string;
anonymousAccess: AnonymousAccessServiceContract | undefined;
+ theme$: Observable;
}) {
if (this.isOpen) {
this.onClose();
@@ -82,30 +87,32 @@ export class ShareMenuManager {
document.body.appendChild(this.container);
const element = (
-
-
-
+
+
+
+
+
);
ReactDOM.render(element, this.container);
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 805213b73fdd0..53ec63d13c06d 100644
--- a/src/plugins/share/public/url_service/redirect/components/page.tsx
+++ b/src/plugins/share/public/url_service/redirect/components/page.tsx
@@ -8,39 +8,47 @@
import * as React from 'react';
import useObservable from 'react-use/lib/useObservable';
+import { Observable } from 'rxjs';
import { EuiPageTemplate } from '@elastic/eui';
+import { CoreTheme } from 'kibana/public';
import { Error } from './error';
import { RedirectManager } from '../redirect_manager';
import { Spinner } from './spinner';
+import { KibanaThemeProvider } from '../../../../../kibana_react/public';
export interface PageProps {
manager: Pick;
+ theme$: Observable;
}
-export const Page: React.FC = ({ manager }) => {
+export const Page: React.FC = ({ manager, theme$ }) => {
const error = useObservable(manager.error$);
if (error) {
return (
+
+
+
+
+
+ );
+ }
+
+ return (
+
-
+
- );
- }
-
- 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 e6f524347e48c..cedeeb014958f 100644
--- a/src/plugins/share/public/url_service/redirect/redirect_manager.ts
+++ b/src/plugins/share/public/url_service/redirect/redirect_manager.ts
@@ -29,7 +29,8 @@ export class RedirectManager {
chromeless: true,
mount: async (params) => {
const { render } = await import('./render');
- const unmount = render(params.element, { manager: this });
+ const theme$ = params.theme$;
+ const unmount = render(params.element, { manager: this, theme$ });
this.onMount(params.history.location.search);
return () => {
unmount();
diff --git a/src/plugins/share/public/url_service/redirect/render.ts b/src/plugins/share/public/url_service/redirect/render.ts
index 2b9c3a50758e4..7ad74ab419067 100644
--- a/src/plugins/share/public/url_service/redirect/render.ts
+++ b/src/plugins/share/public/url_service/redirect/render.ts
@@ -11,7 +11,7 @@ import * as ReactDOM from 'react-dom';
import { Page, PageProps } from './components/page';
export const render = (container: HTMLElement, props: PageProps) => {
- ReactDOM.render(React.createElement(Page, props), container);
+ ReactDOM.render(React.createElement(Page, { ...props }), container);
return () => {
ReactDOM.unmountComponentAtNode(container);
diff --git a/src/plugins/share/tsconfig.json b/src/plugins/share/tsconfig.json
index 1f9c438f03fc4..2633d840895d6 100644
--- a/src/plugins/share/tsconfig.json
+++ b/src/plugins/share/tsconfig.json
@@ -9,6 +9,7 @@
"include": ["common/**/*", "public/**/*", "server/**/*"],
"references": [
{ "path": "../../core/tsconfig.json" },
- { "path": "../kibana_utils/tsconfig.json" },
+ { "path": "../kibana_react/tsconfig.json" },
+ { "path": "../kibana_utils/tsconfig.json" }
]
}
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 91cb8099e8b3c..52c092610ce93 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
@@ -11,6 +11,8 @@ import React from 'react';
import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiPopover } from '@elastic/eui';
import { EventEmitter } from 'events';
import ReactDOM from 'react-dom';
+import { KibanaThemeProvider } from '../../../kibana_react/public';
+import { getTheme } from '../index';
let activeSession: ContextMenuSession | null = null;
@@ -168,20 +170,22 @@ export function openContextMenu(
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
diff --git a/src/plugins/ui_actions/public/index.ts b/src/plugins/ui_actions/public/index.ts
index a93b5e3f958a9..6e138da2d6cd2 100644
--- a/src/plugins/ui_actions/public/index.ts
+++ b/src/plugins/ui_actions/public/index.ts
@@ -7,12 +7,16 @@
*/
import { PluginInitializerContext } from '../../../core/public';
+import type { ThemeServiceStart } from '../../../core/public';
import { UiActionsPlugin } from './plugin';
+import { createGetterSetter } from '../../../plugins/kibana_utils/public';
export function plugin(initializerContext: PluginInitializerContext) {
return new UiActionsPlugin(initializerContext);
}
+export const [getTheme, setTheme] = createGetterSetter('Theme');
+
export type { UiActionsSetup, UiActionsStart } from './plugin';
export type { UiActionsServiceParams } from './service';
export { UiActionsService } from './service';
diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts
index ea6a7e42815cb..a95b45900c748 100644
--- a/src/plugins/ui_actions/public/plugin.ts
+++ b/src/plugins/ui_actions/public/plugin.ts
@@ -10,6 +10,7 @@ import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core
import { PublicMethodsOf } from '@kbn/utility-types';
import { UiActionsService } from './service';
import { rowClickTrigger, visualizeFieldTrigger, visualizeGeoFieldTrigger } from './triggers';
+import { setTheme } from '.';
export type UiActionsSetup = Pick<
UiActionsService,
@@ -29,6 +30,7 @@ export class UiActionsPlugin implements Plugin {
constructor(initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup): UiActionsSetup {
+ setTheme(core.theme);
this.service.registerTrigger(rowClickTrigger);
this.service.registerTrigger(visualizeFieldTrigger);
this.service.registerTrigger(visualizeGeoFieldTrigger);
diff --git a/src/plugins/visualize/public/application/utils/utils.ts b/src/plugins/visualize/public/application/utils/utils.ts
index b0c0ad7848c80..da67c5f4e0f70 100644
--- a/src/plugins/visualize/public/application/utils/utils.ts
+++ b/src/plugins/visualize/public/application/utils/utils.ts
@@ -13,6 +13,7 @@ import { Filter } from '@kbn/es-query';
import { redirectWhenMissing } from '../../../../kibana_utils/public';
import { VisualizeConstants } from '../visualize_constants';
import { VisualizeServices, VisualizeEditorVisInstance } from '../types';
+import { getTheme } from '../../services';
export const addHelpMenuToAppChrome = (chrome: ChromeStart, docLinks: DocLinksStart) => {
chrome.setHelpExtension({
@@ -91,5 +92,6 @@ export const redirectToSavedObjectPage = (
onBeforeRedirect() {
setActiveUrl(VisualizeConstants.LANDING_PAGE_PATH);
},
+ theme: getTheme(),
})(error);
};
diff --git a/src/plugins/visualize/public/plugin.ts b/src/plugins/visualize/public/plugin.ts
index 7ff3434286b6b..6ce010654d7d0 100644
--- a/src/plugins/visualize/public/plugin.ts
+++ b/src/plugins/visualize/public/plugin.ts
@@ -49,6 +49,7 @@ import type { SpacesApi } from '../../../../x-pack/plugins/spaces/public';
import { setVisEditorsRegistry, setUISettings, setUsageCollector } from './services';
import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry';
import { VisualizeLocatorDefinition } from '../common/locator';
+import { setTheme } from './services';
export interface VisualizePluginStartDependencies {
data: DataPublicPluginStart;
@@ -136,6 +137,7 @@ export class VisualizePlugin
stopUrlTracker();
};
+ setTheme(core.theme);
setUISettings(core.uiSettings);
core.application.register({
diff --git a/src/plugins/visualize/public/services.ts b/src/plugins/visualize/public/services.ts
index 3f91762c60780..285abc7c243a9 100644
--- a/src/plugins/visualize/public/services.ts
+++ b/src/plugins/visualize/public/services.ts
@@ -7,7 +7,7 @@
*/
import { createGetterSetter } from '../../../plugins/kibana_utils/public';
-import type { IUiSettingsClient } from '../../../core/public';
+import type { IUiSettingsClient, ThemeServiceStart } from '../../../core/public';
import type { VisEditorsRegistry } from './vis_editors_registry';
import type { UsageCollectionStart } from '../../usage_collection/public';
@@ -20,3 +20,5 @@ export const [getUsageCollector, setUsageCollector] = createGetterSetter('VisEditorsRegistry');
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/x-pack/examples/reporting_example/public/application.tsx b/x-pack/examples/reporting_example/public/application.tsx
index 3e1afd7c517a2..5420d8853259a 100644
--- a/x-pack/examples/reporting_example/public/application.tsx
+++ b/x-pack/examples/reporting_example/public/application.tsx
@@ -9,6 +9,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Switch } from 'react-router-dom';
import { AppMountParameters, CoreStart } from '../../../../src/core/public';
+import { KibanaThemeProvider } from '../../../../../kibana/src/plugins/kibana_react/public';
import { CaptureTest } from './containers/capture_test';
import { Main } from './containers/main';
import { ApplicationContextProvider } from './application_context';
@@ -21,14 +22,17 @@ export const renderApp = (
{ appBasePath, element, history }: AppMountParameters, // FIXME: appBasePath is deprecated
forwardedParams: MyForwardableState
) => {
+ const theme$ = coreStart.theme.theme$;
ReactDOM.render(
-
-
- } />
- } />
-
-
+
+
+
+ } />
+ } />
+
+
+
,
element
);
From 2f5cf5f4b830b4f30e5fc729b4e85b6cbe905aa1 Mon Sep 17 00:00:00 2001
From: shivindera
Date: Wed, 5 Jan 2022 19:00:51 +0100
Subject: [PATCH 2/7] add KibanaThemeProvider to toMountPoint for
kibana-app-services
---
.../application/listing/dashboard_listing.tsx | 1 +
.../public/actions/apply_filter_action.ts | 5 +-
src/plugins/data/public/plugin.ts | 2 +
.../public/search/fetch/handle_response.tsx | 5 +-
.../search_interceptor/search_interceptor.ts | 11 +-
src/plugins/data/public/services.ts | 4 +-
.../query_string_input/query_string_input.tsx | 4 +-
.../shard_failure_open_modal_button.tsx | 5 +-
.../data_view_editor/public/open_editor.tsx | 3 +-
.../public/open_delete_modal.tsx | 3 +-
.../public/open_editor.tsx | 3 +-
.../components/table/table.tsx | 4 +-
.../data_view_management/public/index.ts | 5 +-
.../data_view_management/public/plugin.ts | 2 +
.../data_views/redirect_no_index_pattern.tsx | 7 +-
.../public/lib/panel/embeddable_panel.tsx | 4 +-
.../add_panel/open_add_panel_flyout.tsx | 4 +-
src/plugins/inspector/public/plugin.tsx | 3 +-
.../adapters/ui_to_react_component.test.tsx | 89 ++++++++++++---
.../public/context/context.test.tsx | 96 ++++++++++-------
.../notifications/create_notifications.tsx | 4 +-
.../public/overlays/create_react_overlays.tsx | 10 +-
.../table_list_view/table_list_view.test.tsx | 2 +
.../table_list_view/table_list_view.tsx | 6 +-
.../public/theme/kibana_theme_provider.tsx | 5 +-
.../kibana_react/public/theme/utils.ts | 5 +-
.../ui_settings/use_ui_setting.test.tsx | 53 +++++----
...ate_state_container_react_helpers.test.tsx | 101 +++++++++++-------
src/plugins/kibana_utils/kibana.json | 1 -
.../public/history/redirect_when_missing.tsx | 2 +-
.../kibana_utils/public/theme/index.ts | 9 ++
.../theme/kibana_theme_provider.test.tsx | 88 +++++++++++++++
.../public/theme/kibana_theme_provider.tsx | 33 ++++++
.../kibana_utils/public/theme/utils.test.ts | 19 ++++
.../kibana_utils/public/theme/utils.ts | 19 ++++
src/plugins/kibana_utils/tsconfig.json | 5 +-
.../components/visualize_listing.tsx | 2 +
x-pack/plugins/data_enhanced/public/plugin.ts | 3 +-
.../components/actions/delete_button.tsx | 3 +-
.../components/actions/extend_button.tsx | 3 +-
.../components/actions/inspect_button.tsx | 2 +-
.../components/actions/rename_button.tsx | 3 +-
.../graph/public/apps/listing_route.tsx | 1 +
x-pack/plugins/maps/public/kibana_services.ts | 1 +
.../routes/list_page/maps_list_view.tsx | 2 +
x-pack/plugins/reporting/kibana.json | 2 +-
x-pack/plugins/reporting/public/index.ts | 5 +-
.../public/notifier/general_error.tsx | 4 +-
.../reporting/public/notifier/job_failure.tsx | 7 +-
.../reporting/public/notifier/job_success.tsx | 7 +-
.../public/notifier/job_warning_formulas.tsx | 7 +-
.../public/notifier/job_warning_max_size.tsx | 7 +-
x-pack/plugins/reporting/public/plugin.ts | 3 +-
.../reporting_panel_content.tsx | 4 +-
x-pack/plugins/reporting/tsconfig.json | 12 +--
x-pack/plugins/runtime_fields/README.md | 25 ++---
.../runtime_fields/public/load_editor.tsx | 5 +-
57 files changed, 548 insertions(+), 182 deletions(-)
create mode 100644 src/plugins/kibana_utils/public/theme/index.ts
create mode 100644 src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx
create mode 100644 src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx
create mode 100644 src/plugins/kibana_utils/public/theme/utils.test.ts
create mode 100644 src/plugins/kibana_utils/public/theme/utils.ts
diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx
index deb8671edb97d..5b53fc47e06a4 100644
--- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx
+++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx
@@ -297,6 +297,7 @@ export const DashboardListing = ({
listingLimit,
tableColumns,
}}
+ theme={core.theme}
>
- >
+ >,
+ { theme$: getTheme().theme$ }
);
getNotifications().toasts.addWarning({ title, text });
diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
index 9e968c9bae8a0..244f0e065f9df 100644
--- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
+++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
@@ -51,6 +51,7 @@ import { ISessionService, SearchSessionState } from '../session';
import { SearchResponseCache } from './search_response_cache';
import { createRequestHash } from './utils';
import { SearchAbortController } from './search_abort_controller';
+import { getTheme } from '../../services';
export interface SearchInterceptorDeps {
bfetch: BfetchPublicSetup;
@@ -377,7 +378,7 @@ export class SearchInterceptor {
private showTimeoutErrorToast = (e: SearchTimeoutError, sessionId?: string) => {
this.deps.toasts.addDanger({
title: 'Timed out',
- text: toMountPoint(e.getErrorMessage(this.application)),
+ text: toMountPoint(e.getErrorMessage(this.application), { theme$: getTheme().theme$ }),
});
};
@@ -392,7 +393,9 @@ export class SearchInterceptor {
this.deps.toasts.addWarning(
{
title: 'Your search session is still running',
- text: toMountPoint(SearchSessionIncompleteWarning(this.docLinks)),
+ text: toMountPoint(SearchSessionIncompleteWarning(this.docLinks), {
+ theme$: getTheme().theme$,
+ }),
},
{
toastLifeTimeMs: 60000,
@@ -423,14 +426,14 @@ export class SearchInterceptor {
title: i18n.translate('data.search.esErrorTitle', {
defaultMessage: 'Cannot retrieve search results',
}),
- text: toMountPoint(e.getErrorMessage(this.application)),
+ text: toMountPoint(e.getErrorMessage(this.application), { theme$: getTheme().theme$ }),
});
} else if (e.constructor.name === 'HttpFetchError') {
this.deps.toasts.addDanger({
title: i18n.translate('data.search.httpErrorTitle', {
defaultMessage: 'Cannot retrieve your data',
}),
- text: toMountPoint(getHttpError(e.message)),
+ text: toMountPoint(getHttpError(e.message), { theme$: getTheme().theme$ }),
});
} else {
this.deps.toasts.addError(e, {
diff --git a/src/plugins/data/public/services.ts b/src/plugins/data/public/services.ts
index c1a0ae1ac1b53..5c52a1e695359 100644
--- a/src/plugins/data/public/services.ts
+++ b/src/plugins/data/public/services.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { NotificationsStart, CoreStart } from 'src/core/public';
+import { NotificationsStart, CoreStart, ThemeServiceStart } from 'src/core/public';
import { createGetterSetter } from '../../kibana_utils/public';
import { IndexPatternsContract } from './data_views';
import { DataPublicPluginStart } from './types';
@@ -24,3 +24,5 @@ export const [getIndexPatterns, setIndexPatterns] =
export const [getSearchService, setSearchService] =
createGetterSetter('Search');
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
index 2e150b2c1e1bc..bfc1cad560bb9 100644
--- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
@@ -39,6 +39,7 @@ import type { PersistedLog } from '../../query';
import type { SuggestionsListSize } from '../typeahead/suggestions_component';
import { SuggestionsComponent } from '..';
import { KIBANA_USER_QUERY_LANGUAGE_KEY, getFieldSubtypeNested } from '../../../common';
+import { getTheme } from '../../services';
export interface QueryStringInputProps {
indexPatterns: Array;
@@ -475,7 +476,8 @@ export default class QueryStringInputUI extends Component {
-
+ ,
+ { theme$: getTheme().theme$ }
),
});
}
diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
index 32ebd83aa47f0..c8a217015d356 100644
--- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
+++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
@@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButton, EuiTextAlign } from '@elastic/eui';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { getOverlays } from '../../services';
+import { getOverlays, getTheme } from '../../services';
import { toMountPoint } from '../../../../kibana_react/public';
import { ShardFailureModal } from './shard_failure_modal';
import { ShardFailureRequest } from './shard_failure_types';
@@ -38,7 +38,8 @@ export default function ShardFailureOpenModalButton({
response={response}
title={title}
onClose={() => modal.close()}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
{
className: 'shardFailureModal',
diff --git a/src/plugins/data_view_editor/public/open_editor.tsx b/src/plugins/data_view_editor/public/open_editor.tsx
index 98843d6d1698a..fcf0fad5a32b0 100644
--- a/src/plugins/data_view_editor/public/open_editor.tsx
+++ b/src/plugins/data_view_editor/public/open_editor.tsx
@@ -79,7 +79,8 @@ export const getEditorOpener =
requireTimestampField={requireTimestampField}
/>
-
+ ,
+ { theme$: core.theme.theme$ }
),
{
hideCloseButton: true,
diff --git a/src/plugins/data_view_field_editor/public/open_delete_modal.tsx b/src/plugins/data_view_field_editor/public/open_delete_modal.tsx
index 84e3885ddb605..f44367d16d08d 100644
--- a/src/plugins/data_view_field_editor/public/open_delete_modal.tsx
+++ b/src/plugins/data_view_field_editor/public/open_delete_modal.tsx
@@ -75,7 +75,8 @@ export const getFieldDeleteModalOpener =
fieldsToDelete={fieldsToDelete}
closeModal={closeModal}
confirmDelete={onConfirmDelete}
- />
+ />,
+ { theme$: core.theme.theme$ }
)
);
diff --git a/src/plugins/data_view_field_editor/public/open_editor.tsx b/src/plugins/data_view_field_editor/public/open_editor.tsx
index 277d7f5c549ae..c66e8183b9ab6 100644
--- a/src/plugins/data_view_field_editor/public/open_editor.tsx
+++ b/src/plugins/data_view_field_editor/public/open_editor.tsx
@@ -128,7 +128,8 @@ export const getFieldEditorOpener =
fieldFormats={fieldFormats}
uiSettings={uiSettings}
/>
-
+ ,
+ { theme$: core.theme.theme$ }
),
{
className: euiFlyoutClassname,
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
index 6a82d0380629c..fa696625da52c 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
@@ -32,6 +32,7 @@ import { toMountPoint } from '../../../../../../../kibana_react/public';
import { IIndexPattern } from '../../../../../../../data/public';
import { IndexedFieldItem } from '../../types';
+import { getTheme } from '../../../../../';
// localized labels
const additionalInfoAriaLabel = i18n.translate(
@@ -322,7 +323,8 @@ const getConflictBtn = (
},
fieldName,
conflictDescriptions,
- })
+ }),
+ { theme$: getTheme().theme$ }
)
);
};
diff --git a/src/plugins/data_view_management/public/index.ts b/src/plugins/data_view_management/public/index.ts
index 65b71ee6053e3..01f6445efb56c 100644
--- a/src/plugins/data_view_management/public/index.ts
+++ b/src/plugins/data_view_management/public/index.ts
@@ -17,10 +17,13 @@
* in the setup/start interfaces in `plugin.ts`. The remaining items exported here are
* either types, or static code.
*/
-import { PluginInitializerContext } from 'src/core/public';
+import { PluginInitializerContext, ThemeServiceStart } from 'src/core/public';
+import { createGetterSetter } from '../../kibana_utils/public';
import { IndexPatternManagementPlugin } from './plugin';
export type { IndexPatternManagementSetup, IndexPatternManagementStart } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new IndexPatternManagementPlugin(initializerContext);
}
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/data_view_management/public/plugin.ts b/src/plugins/data_view_management/public/plugin.ts
index 742a623dcb084..7d249c5d6a3b8 100644
--- a/src/plugins/data_view_management/public/plugin.ts
+++ b/src/plugins/data_view_management/public/plugin.ts
@@ -14,6 +14,7 @@ import { UrlForwardingSetup } from '../../url_forwarding/public';
import { ManagementSetup } from '../../management/public';
import { IndexPatternFieldEditorStart } from '../../data_view_field_editor/public';
import { DataViewEditorStart } from '../../data_view_editor/public';
+import { setTheme } from '.';
export interface IndexPatternManagementSetupDependencies {
management: ManagementSetup;
@@ -54,6 +55,7 @@ export class IndexPatternManagementPlugin
{ management, urlForwarding }: IndexPatternManagementSetupDependencies
) {
const kibanaSection = management.sections.section.kibana;
+ setTheme(core.theme);
if (!kibanaSection) {
throw new Error('`kibana` management section not found.');
diff --git a/src/plugins/data_views/public/data_views/redirect_no_index_pattern.tsx b/src/plugins/data_views/public/data_views/redirect_no_index_pattern.tsx
index 086cd92a92d82..fc7b8c9eb42b6 100644
--- a/src/plugins/data_views/public/data_views/redirect_no_index_pattern.tsx
+++ b/src/plugins/data_views/public/data_views/redirect_no_index_pattern.tsx
@@ -18,7 +18,8 @@ export const onRedirectNoIndexPattern =
(
capabilities: CoreStart['application']['capabilities'],
navigateToApp: CoreStart['application']['navigateToApp'],
- overlays: CoreStart['overlays']
+ overlays: CoreStart['overlays'],
+ theme: CoreStart['theme']
) =>
() => {
const canManageIndexPatterns = capabilities.management.kibana.indexPatterns;
@@ -38,7 +39,9 @@ export const onRedirectNoIndexPattern =
// give them a friendly info message instead of a terse error message
bannerId = overlays.banners.replace(
bannerId,
- toMountPoint()
+ toMountPoint(, {
+ theme$: theme.theme$,
+ })
);
// hide the message after the user has had a chance to acknowledge it -- so it doesn't permanently stick around
diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
index 6748e9f3b1d08..8c09e9d741e79 100644
--- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
+++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
@@ -42,6 +42,7 @@ import { CustomizePanelModal } from './panel_header/panel_actions/customize_titl
import { EmbeddableStart } from '../../plugin';
import { EmbeddableErrorLabel } from './embeddable_error_label';
import { EmbeddableStateTransfer, ErrorEmbeddable } from '..';
+import { getTheme } from '../..';
const sortByOrderField = (
{ order: orderA }: { order?: number },
@@ -360,7 +361,8 @@ export class EmbeddablePanel extends React.Component {
resolve({ title, hideTitle });
}}
cancel={() => session.close()}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
{
'data-test-subj': 'customizePanel',
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
index fe54b3d134aa0..8a648c370d083 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
@@ -13,6 +13,7 @@ import { toMountPoint } from '../../../../../../../kibana_react/public';
import { IContainer } from '../../../../containers';
import { AddPanelFlyout } from './add_panel_flyout';
import { UsageCollectionStart } from '../../../../../../../usage_collection/public';
+import { getTheme } from '../../../../../';
export function openAddPanelFlyout(options: {
embeddable: IContainer;
@@ -49,7 +50,8 @@ export function openAddPanelFlyout(options: {
reportUiCounter={reportUiCounter}
SavedObjectFinder={SavedObjectFinder}
showCreateNewMenu={showCreateNewMenu}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
{
'data-test-subj': 'dashboardAddPanel',
diff --git a/src/plugins/inspector/public/plugin.tsx b/src/plugins/inspector/public/plugin.tsx
index e561a9719b3fb..14a141f7c2ec1 100644
--- a/src/plugins/inspector/public/plugin.tsx
+++ b/src/plugins/inspector/public/plugin.tsx
@@ -106,7 +106,8 @@ export class InspectorPublicPlugin implements Plugin {
uiSettings: core.uiSettings,
share: startDeps.share,
}}
- />
+ />,
+ { theme$: core.theme.theme$ }
),
{
'data-test-subj': 'inspectorPanel',
diff --git a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
index 0a435f89bff37..89a41e1d57461 100644
--- a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
+++ b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
@@ -8,9 +8,14 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
+import { ThemeServiceStart } from '../../../../core/public';
+import { themeServiceMock } from '../../../../core/public/mocks';
import { UiComponent } from '../../../kibana_utils/public';
import { uiToReactComponent } from './ui_to_react_component';
import { reactToUiComponent } from './react_to_ui_component';
+import { KibanaThemeProvider } from '..';
+
+const theme: ThemeServiceStart = themeServiceMock.createStartContract();
const UiComp: UiComponent<{ cnt?: number }> = () => ({
render: (el, { cnt = 0 }) => {
@@ -24,7 +29,12 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.innerHTML).toBe('cnt: 0
');
});
@@ -33,7 +43,12 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.innerHTML).toBe('cnt: 5
');
});
@@ -42,11 +57,21 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.innerHTML).toBe('cnt: 1
');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.innerHTML).toBe('cnt: 2
');
});
@@ -61,7 +86,12 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp2);
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
ReactDOM.unmountComponentAtNode(div);
expect(div.innerHTML).toBe('');
@@ -81,7 +111,12 @@ describe('uiToReactComponent', () => {
expect(unmount).toHaveBeenCalledTimes(0);
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(unmount).toHaveBeenCalledTimes(0);
@@ -103,15 +138,30 @@ describe('uiToReactComponent', () => {
expect(render).toHaveBeenCalledTimes(0);
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(render).toHaveBeenCalledTimes(1);
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(render).toHaveBeenCalledTimes(2);
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(render).toHaveBeenCalledTimes(3);
});
@@ -120,7 +170,12 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp, 'span');
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.innerHTML).toBe('cnt: 5');
});
@@ -132,11 +187,21 @@ test('can adapt component many times', () => {
);
const div = document.createElement('div');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.textContent).toBe('cnt: 0');
- ReactDOM.render(, div);
+ ReactDOM.render(
+
+
+ ,
+ div
+ );
expect(div.textContent).toBe('cnt: 123');
});
diff --git a/src/plugins/kibana_react/public/context/context.test.tsx b/src/plugins/kibana_react/public/context/context.test.tsx
index a806f3eb66f75..90d175b422bd1 100644
--- a/src/plugins/kibana_react/public/context/context.test.tsx
+++ b/src/plugins/kibana_react/public/context/context.test.tsx
@@ -9,10 +9,12 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { context, createKibanaReactContext, useKibana, KibanaContextProvider } from './context';
-import { coreMock, overlayServiceMock } from '../../../../core/public/mocks';
-import { CoreStart } from '../../../../core/public';
+import { CoreStart, ThemeServiceStart } from '../../../../core/public';
+import { coreMock, overlayServiceMock, themeServiceMock } from '../../../../core/public/mocks';
+import { KibanaThemeProvider } from '..';
let container: HTMLDivElement | null;
+const theme: ThemeServiceStart = themeServiceMock.createStartContract();
beforeEach(() => {
container = document.createElement('div');
@@ -27,9 +29,11 @@ afterEach(() => {
test('can mount without crashing', () => {
const services = coreMock.createStart();
ReactDOM.render(
-
- Hello world
- ,
+
+
+ Hello world
+
+ ,
container
);
});
@@ -43,9 +47,11 @@ test('useKibana() hook retrieves Kibana context', () => {
const core = coreMock.createStart();
(core as any).foo = 'bar';
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -60,9 +66,11 @@ test('createContext() creates context that can be consumed by useKibana() hook',
const { Provider } = createKibanaReactContext(services);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -83,9 +91,11 @@ test('services, notifications and overlays objects are always available', () =>
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
});
@@ -102,9 +112,11 @@ test(' provider provides default kibana-react context', (
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
});
@@ -117,9 +129,11 @@ test(' can set custom services in context', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
});
@@ -134,13 +148,15 @@ test('nested override and merge services', () => {
};
ReactDOM.render(
-
-
-
-
+
+
+
+
+
+
- ,
+ ,
container
);
});
@@ -162,11 +178,13 @@ test('overlays wrapper uses the closest overlays service', () => {
} as Partial;
ReactDOM.render(
-
-
-
+
+
+
+
+
- ,
+ ,
container
);
@@ -200,11 +218,13 @@ test('notifications wrapper uses the closest notifications service', () => {
} as Partial;
ReactDOM.render(
-
-
-
+
+
+
+
+
- ,
+ ,
container
);
@@ -239,11 +259,13 @@ test('overlays wrapper uses available overlays service, higher up in
-
-
+
+
+
+
+
- ,
+ ,
container
);
diff --git a/src/plugins/kibana_react/public/notifications/create_notifications.tsx b/src/plugins/kibana_react/public/notifications/create_notifications.tsx
index 2e59e611fc421..8eb16a5580ab3 100644
--- a/src/plugins/kibana_react/public/notifications/create_notifications.tsx
+++ b/src/plugins/kibana_react/public/notifications/create_notifications.tsx
@@ -24,8 +24,8 @@ export const createNotifications = (services: KibanaServices): KibanaReactNotifi
throw new TypeError('Could not show notification as notifications service is not available.');
}
services.notifications!.toasts.add({
- title: toMountPoint(title),
- text: toMountPoint(<>{body || null}>),
+ title: toMountPoint(title, { theme$: services.theme?.theme$ }),
+ text: toMountPoint(<>{body || null}>, { theme$: services.theme?.theme$ }),
color,
iconType,
toastLifeTimeMs,
diff --git a/src/plugins/kibana_react/public/overlays/create_react_overlays.tsx b/src/plugins/kibana_react/public/overlays/create_react_overlays.tsx
index 3274699e4bd69..4349e39d04fd5 100644
--- a/src/plugins/kibana_react/public/overlays/create_react_overlays.tsx
+++ b/src/plugins/kibana_react/public/overlays/create_react_overlays.tsx
@@ -20,12 +20,18 @@ export const createReactOverlays = (services: KibanaServices): KibanaReactOverla
const openFlyout: KibanaReactOverlays['openFlyout'] = (node, options?) => {
checkCoreService();
- return services.overlays!.openFlyout(toMountPoint(<>{node}>), options);
+ return services.overlays!.openFlyout(
+ toMountPoint(<>{node}>, { theme$: services.theme?.theme$ }),
+ options
+ );
};
const openModal: KibanaReactOverlays['openModal'] = (node, options?) => {
checkCoreService();
- return services.overlays!.openModal(toMountPoint(<>{node}>), options);
+ return services.overlays!.openModal(
+ toMountPoint(<>{node}>, { theme$: services.theme?.theme$ }),
+ options
+ );
};
const overlays: KibanaReactOverlays = {
diff --git a/src/plugins/kibana_react/public/table_list_view/table_list_view.test.tsx b/src/plugins/kibana_react/public/table_list_view/table_list_view.test.tsx
index 3663f156c69cb..bdc5ca30216bc 100644
--- a/src/plugins/kibana_react/public/table_list_view/table_list_view.test.tsx
+++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.test.tsx
@@ -10,6 +10,7 @@ import { EuiEmptyPrompt } from '@elastic/eui';
import { shallowWithIntl } from '@kbn/test/jest';
import { ToastsStart } from 'kibana/public';
import React from 'react';
+import { themeServiceMock } from '../../../../../src/core/public/mocks';
import { TableListView } from './table_list_view';
const requiredProps = {
@@ -24,6 +25,7 @@ const requiredProps = {
tableCaption: 'test caption',
toastNotifications: {} as ToastsStart,
findItems: jest.fn(() => Promise.resolve({ total: 0, hits: [] })),
+ theme: themeServiceMock.createStartContract(),
};
describe('TableListView', () => {
diff --git a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
index 65c62543538d0..dd023d522dbb6 100644
--- a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
+++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
@@ -20,7 +20,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { HttpFetchError, ToastsStart } from 'kibana/public';
+import { ThemeServiceStart, HttpFetchError, ToastsStart } from 'kibana/public';
import { debounce, keyBy, sortBy, uniq } from 'lodash';
import React from 'react';
import { KibanaPageTemplate } from '../page_template';
@@ -57,6 +57,7 @@ export interface TableListViewProps {
*/
tableCaption: string;
searchFilters?: SearchFilterConfig[];
+ theme: ThemeServiceStart;
}
export interface TableListViewState {
@@ -177,7 +178,8 @@ class TableListView extends React.Component<
id="kibana-react.tableListView.listing.unableToDeleteDangerMessage"
defaultMessage="Unable to delete {entityName}(s)"
values={{ entityName: this.props.entityName }}
- />
+ />,
+ { theme$: this.props.theme.theme$ }
),
text: `${error}`,
});
diff --git a/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx b/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx
index 65d640f34a2ca..56ca7642f1cde 100644
--- a/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx
+++ b/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx
@@ -21,8 +21,9 @@ const defaultTheme: CoreTheme = {
darkMode: false,
};
-// IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
-// That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.
+/* IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
+That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.*/
+// IMPORTANT: This code has been copied to the `kibana_utils` plugin, to avoid cyclical dependency, any changes here should be applied there too.
export const KibanaThemeProvider: FC = ({ theme$, children }) => {
const theme = useObservable(theme$, defaultTheme);
diff --git a/src/plugins/kibana_react/public/theme/utils.ts b/src/plugins/kibana_react/public/theme/utils.ts
index 161f3a5e36b76..fe8092949d431 100644
--- a/src/plugins/kibana_react/public/theme/utils.ts
+++ b/src/plugins/kibana_react/public/theme/utils.ts
@@ -10,8 +10,9 @@ import { COLOR_MODES_STANDARD } from '@elastic/eui';
import type { EuiThemeColorModeStandard } from '@elastic/eui';
import type { CoreTheme } from '../../../../core/public';
-// IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
-// That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.
+/* IMPORTANT: This code has been copied to the `interactive_setup` plugin, any changes here should be applied there too.
+That copy and this comment can be removed once https://github.com/elastic/kibana/issues/119204 is implemented.*/
+// IMPORTANT: This code has been copied to the `kibana_utils` plugin, to avoid cyclical dependency, any changes here should be applied there too.
export const getColorMode = (theme: CoreTheme): EuiThemeColorModeStandard => {
return theme.darkMode ? COLOR_MODES_STANDARD.dark : COLOR_MODES_STANDARD.light;
diff --git a/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx b/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
index 44dea2aa420a7..d937388164b9d 100644
--- a/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
+++ b/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
@@ -13,12 +13,15 @@ import { useUiSetting$ } from './use_ui_setting';
import { createKibanaReactContext } from '../context';
import { KibanaServices } from '../context/types';
import { Subject } from 'rxjs';
-import { coreMock } from '../../../../core/public/mocks';
+import { ThemeServiceStart } from '../../../../core/public';
+import { coreMock, themeServiceMock } from '../../../../core/public/mocks';
import useObservable from 'react-use/lib/useObservable';
+import { KibanaThemeProvider } from '..';
jest.mock('react-use/lib/useObservable');
const useObservableSpy = useObservable as any as jest.SpyInstance;
useObservableSpy.mockImplementation((observable, def) => def);
+const theme: ThemeServiceStart = themeServiceMock.createStartContract();
const mock = (): [KibanaServices, Subject] => {
const core = coreMock.createStart();
@@ -65,9 +68,11 @@ describe('useUiSetting', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -82,9 +87,11 @@ describe('useUiSetting', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -114,9 +121,11 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -131,9 +140,11 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -147,9 +158,11 @@ describe('useUiSetting$', () => {
expect(useObservableSpy).toHaveBeenCalledTimes(0);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -162,9 +175,11 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
diff --git a/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx b/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
index 997a3710c58cb..79ce6b4015975 100644
--- a/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
+++ b/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
@@ -11,8 +11,13 @@ import * as ReactDOM from 'react-dom';
import { act, Simulate } from 'react-dom/test-utils';
import { createStateContainer } from './create_state_container';
import { createStateContainerReactHelpers } from './create_state_container_react_helpers';
+import { ThemeServiceStart } from '../../../../core/public';
+import { themeServiceMock } from '../../../../core/public/mocks';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { KibanaThemeProvider } from '../../public/theme';
let container: HTMLDivElement | null;
+const theme: ThemeServiceStart = themeServiceMock.createStartContract();
beforeEach(() => {
container = document.createElement('div');
@@ -40,9 +45,11 @@ test(' passes state to ', () => {
const { Provider, Consumer } = createStateContainerReactHelpers();
ReactDOM.render(
-
- {(s: typeof stateContainer) => s.get().hello}
- ,
+
+
+ {(s: typeof stateContainer) => s.get().hello}
+
+ ,
container
);
@@ -72,9 +79,11 @@ test(' passes state to connect()()', () => {
const DemoConnected = connect(mergeProps)(Demo);
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -87,9 +96,11 @@ test('context receives stateContainer', () => {
ReactDOM.render(
/* eslint-disable @typescript-eslint/no-shadow */
-
- {(stateContainer) => stateContainer.get().foo}
- ,
+
+
+ {(stateContainer) => stateContainer.get().foo}
+
+ ,
/* eslint-enable @typescript-eslint/no-shadow */
container
);
@@ -111,9 +122,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -131,9 +144,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -154,9 +169,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -196,9 +213,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -231,9 +250,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -256,9 +277,11 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -287,9 +310,11 @@ describe('hooks', () => {
return <>{value}>;
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -323,9 +348,11 @@ describe('hooks', () => {
return <>{JSON.stringify(value)}>;
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
@@ -365,9 +392,11 @@ describe('hooks', () => {
return <>{JSON.stringify(value)}>;
};
ReactDOM.render(
-
-
- ,
+
+
+
+
+ ,
container
);
diff --git a/src/plugins/kibana_utils/kibana.json b/src/plugins/kibana_utils/kibana.json
index 0cdf019e17417..7c0f73a160970 100644
--- a/src/plugins/kibana_utils/kibana.json
+++ b/src/plugins/kibana_utils/kibana.json
@@ -7,6 +7,5 @@
"name": "App Services",
"githubTeam": "kibana-app-services"
},
- "requiredBundles": ["kibanaReact"],
"extraPublicDirs": ["common", "demos/state_containers/todomvc", "common/state_containers"]
}
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 39a6175bd3a5c..6913c94a6bb5f 100644
--- a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx
+++ b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx
@@ -15,7 +15,7 @@ import ReactDOM from 'react-dom';
import { ApplicationStart, HttpStart, ToastsSetup } from 'kibana/public';
import type { ThemeServiceStart } from '../../../../core/public';
import { SavedObjectNotFound } from '..';
-import { KibanaThemeProvider } from '../../../kibana_react/public';
+import { KibanaThemeProvider } from '../theme';
const ReactMarkdown = React.lazy(() => import('react-markdown'));
const ErrorRenderer = (props: { children: string }) => (
diff --git a/src/plugins/kibana_utils/public/theme/index.ts b/src/plugins/kibana_utils/public/theme/index.ts
new file mode 100644
index 0000000000000..165c5ef9195c2
--- /dev/null
+++ b/src/plugins/kibana_utils/public/theme/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { KibanaThemeProvider } from './kibana_theme_provider';
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
new file mode 100644
index 0000000000000..21059bd4a8236
--- /dev/null
+++ b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.test.tsx
@@ -0,0 +1,88 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { useEuiTheme } from '@elastic/eui';
+import type { ReactWrapper } from 'enzyme';
+import type { FC } from 'react';
+import React, { useEffect } from 'react';
+import { act } from 'react-dom/test-utils';
+import { BehaviorSubject, of } from 'rxjs';
+
+import { mountWithIntl } from '@kbn/test/jest';
+import type { CoreTheme } from 'src/core/public';
+
+import { KibanaThemeProvider } from './kibana_theme_provider';
+
+describe('KibanaThemeProvider', () => {
+ let euiTheme: ReturnType | undefined;
+
+ beforeEach(() => {
+ euiTheme = undefined;
+ });
+
+ const flushPromises = async () => {
+ await new Promise(async (resolve, reject) => {
+ try {
+ setImmediate(() => resolve());
+ } catch (error) {
+ reject(error);
+ }
+ });
+ };
+
+ const InnerComponent: FC = () => {
+ const theme = useEuiTheme();
+ useEffect(() => {
+ euiTheme = theme;
+ }, [theme]);
+ return foo
;
+ };
+
+ const refresh = async (wrapper: ReactWrapper) => {
+ await act(async () => {
+ await flushPromises();
+ wrapper.update();
+ });
+ };
+
+ it('exposes the EUI theme provider', async () => {
+ const coreTheme: CoreTheme = { darkMode: true };
+
+ const wrapper = mountWithIntl(
+
+
+
+ );
+
+ await refresh(wrapper);
+
+ expect(euiTheme!.colorMode).toEqual('DARK');
+ });
+
+ it('propagates changes of the coreTheme observable', async () => {
+ const coreTheme$ = new BehaviorSubject({ darkMode: true });
+
+ const wrapper = mountWithIntl(
+
+
+
+ );
+
+ await refresh(wrapper);
+
+ expect(euiTheme!.colorMode).toEqual('DARK');
+
+ await act(async () => {
+ coreTheme$.next({ darkMode: false });
+ });
+
+ await refresh(wrapper);
+
+ expect(euiTheme!.colorMode).toEqual('LIGHT');
+ });
+});
diff --git a/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx
new file mode 100644
index 0000000000000..7c7963eff984b
--- /dev/null
+++ b/src/plugins/kibana_utils/public/theme/kibana_theme_provider.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { EuiThemeProvider } from '@elastic/eui';
+import type { FC } from 'react';
+import React, { useMemo } from 'react';
+import useObservable from 'react-use/lib/useObservable';
+import type { Observable } from 'rxjs';
+
+import type { CoreTheme } from '../../../../core/public';
+import { getColorMode } from './utils';
+
+interface KibanaThemeProviderProps {
+ theme$: Observable;
+}
+
+const defaultTheme: CoreTheme = {
+ darkMode: false,
+};
+
+/**
+ * Copied from the `kibana_react` plugin, to avoid cyclical dependency
+ */
+export const KibanaThemeProvider: FC = ({ theme$, children }) => {
+ const theme = useObservable(theme$, defaultTheme);
+ const colorMode = useMemo(() => getColorMode(theme), [theme]);
+ return {children};
+};
diff --git a/src/plugins/kibana_utils/public/theme/utils.test.ts b/src/plugins/kibana_utils/public/theme/utils.test.ts
new file mode 100644
index 0000000000000..57b37f4fb2f62
--- /dev/null
+++ b/src/plugins/kibana_utils/public/theme/utils.test.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { getColorMode } from './utils';
+
+describe('getColorMode', () => {
+ it('returns the correct `colorMode` when `darkMode` is enabled', () => {
+ expect(getColorMode({ darkMode: true })).toEqual('DARK');
+ });
+
+ it('returns the correct `colorMode` when `darkMode` is disabled', () => {
+ expect(getColorMode({ darkMode: false })).toEqual('LIGHT');
+ });
+});
diff --git a/src/plugins/kibana_utils/public/theme/utils.ts b/src/plugins/kibana_utils/public/theme/utils.ts
new file mode 100644
index 0000000000000..887e4fe61fbe1
--- /dev/null
+++ b/src/plugins/kibana_utils/public/theme/utils.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { COLOR_MODES_STANDARD } from '@elastic/eui';
+import type { EuiThemeColorModeStandard } from '@elastic/eui';
+
+import type { CoreTheme } from '../../../../core/public';
+
+/**
+ * Copied from the `kibana_react` plugin, to avoid cyclical dependency
+ */
+export const getColorMode = (theme: CoreTheme): EuiThemeColorModeStandard => {
+ return theme.darkMode ? COLOR_MODES_STANDARD.dark : COLOR_MODES_STANDARD.light;
+};
diff --git a/src/plugins/kibana_utils/tsconfig.json b/src/plugins/kibana_utils/tsconfig.json
index 50888e9a7f85b..0fba68be6aa57 100644
--- a/src/plugins/kibana_utils/tsconfig.json
+++ b/src/plugins/kibana_utils/tsconfig.json
@@ -14,8 +14,5 @@
"index.ts",
"../../../typings/**/*"
],
- "references": [
- { "path": "../../core/tsconfig.json" },
- { "path": "../kibana_react/tsconfig.json" }
- ]
+ "references": [{ "path": "../../core/tsconfig.json" }]
}
diff --git a/src/plugins/visualize/public/application/components/visualize_listing.tsx b/src/plugins/visualize/public/application/components/visualize_listing.tsx
index e4516cdd7fed3..5816626b644a8 100644
--- a/src/plugins/visualize/public/application/components/visualize_listing.tsx
+++ b/src/plugins/visualize/public/application/components/visualize_listing.tsx
@@ -23,6 +23,7 @@ import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../visualizations/public
import { VisualizeServices } from '../types';
import { VisualizeConstants } from '../visualize_constants';
import { getTableColumns, getNoItemsMessage } from '../utils';
+import { getTheme } from '../../services';
export const VisualizeListing = () => {
const {
@@ -198,6 +199,7 @@ export const VisualizeListing = () => {
})}
toastNotifications={toastNotifications}
searchFilters={searchFilters}
+ theme={getTheme()}
>
{dashboard.dashboardFeatureFlagConfig.allowByValueEmbeddables &&
dashboardCapabilities.createNew && (
diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts
index 6ec645c932e05..ee76cce9b9d2b 100644
--- a/x-pack/plugins/data_enhanced/public/plugin.ts
+++ b/x-pack/plugins/data_enhanced/public/plugin.ts
@@ -81,7 +81,8 @@ export class DataEnhancedPlugin
usageCollector: this.usageCollector,
tourDisabled: plugins.screenshotMode.isScreenshotMode(),
})
- )
+ ),
+ { theme$: core.theme.theme$ }
),
});
}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/delete_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/delete_button.tsx
index 3d1a3052e720b..127a63b647a24 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/delete_button.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/delete_button.tsx
@@ -74,7 +74,8 @@ export const createDeleteActionDescriptor = (
onClick: async () => {
const ref = core.overlays.openModal(
toMountPoint(
- ref?.close()} searchSession={uiSession} api={api} />
+ ref?.close()} searchSession={uiSession} api={api} />,
+ { theme$: core.theme.theme$ }
)
);
await ref.onClose;
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
index 6989caeca359e..d8b5e9de16688 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
@@ -81,7 +81,8 @@ export const createExtendActionDescriptor = (
onClick: async () => {
const ref = core.overlays.openModal(
toMountPoint(
- ref?.close()} searchSession={uiSession} api={api} />
+ ref?.close()} searchSession={uiSession} api={api} />,
+ { theme$: core.theme.theme$ }
)
);
await ref.onClose;
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx
index 23c010e0fbc67..2b917c28c4b3b 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx
@@ -97,7 +97,7 @@ export const createInspectActionDescriptor = (
),
onClick: async () => {
const flyout = ;
- const overlay = core.overlays.openFlyout(toMountPoint(flyout));
+ const overlay = core.overlays.openFlyout(toMountPoint(flyout, { theme$: core.theme.theme$ }));
await overlay.onClose;
},
});
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/rename_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/rename_button.tsx
index beb773e057cb9..d663d0da5cad7 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/rename_button.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/rename_button.tsx
@@ -113,7 +113,8 @@ export const createRenameActionDescriptor = (
onClick: async () => {
const ref = core.overlays.openModal(
toMountPoint(
- ref?.close()} api={api} searchSession={uiSession} />
+ ref?.close()} api={api} searchSession={uiSession} />,
+ { theme$: core.theme.theme$ }
)
);
await ref.onClose;
diff --git a/x-pack/plugins/graph/public/apps/listing_route.tsx b/x-pack/plugins/graph/public/apps/listing_route.tsx
index 4ed0789f33fdf..dc70d84155bf9 100644
--- a/x-pack/plugins/graph/public/apps/listing_route.tsx
+++ b/x-pack/plugins/graph/public/apps/listing_route.tsx
@@ -102,6 +102,7 @@ export function ListingRoute({
tableListTitle={i18n.translate('xpack.graph.listing.graphsTitle', {
defaultMessage: 'Graphs',
})}
+ theme={coreStart.theme}
/>
);
diff --git a/x-pack/plugins/maps/public/kibana_services.ts b/x-pack/plugins/maps/public/kibana_services.ts
index 5ad3a1d3fd23d..39fe1775af12a 100644
--- a/x-pack/plugins/maps/public/kibana_services.ts
+++ b/x-pack/plugins/maps/public/kibana_services.ts
@@ -54,6 +54,7 @@ export const getSavedObjectsTagging = () => pluginsStart.savedObjectsTagging;
export const getPresentationUtilContext = () => pluginsStart.presentationUtil.ContextProvider;
export const getSecurityService = () => pluginsStart.security;
export const getSpacesApi = () => pluginsStart.spaces;
+export const getTheme = () => coreStart.theme;
// xpack.maps.* kibana.yml settings from this plugin
let mapAppConfig: MapsConfigType;
diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx
index 7dc8c9c88d4ca..571cba64a06c4 100644
--- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx
+++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx
@@ -21,6 +21,7 @@ import {
getSavedObjectsClient,
getSavedObjectsTagging,
getSavedObjects,
+ getTheme,
} from '../../kibana_services';
import { getAppTitle } from '../../../common/i18n_getters';
import { MapSavedObjectAttributes } from '../../../common/map_saved_object_type';
@@ -148,6 +149,7 @@ export function MapsListView() {
tableListTitle={getAppTitle()}
toastNotifications={getToasts()}
searchFilters={searchFilters}
+ theme={getTheme()}
/>
);
}
diff --git a/x-pack/plugins/reporting/kibana.json b/x-pack/plugins/reporting/kibana.json
index 123c23e5e1c29..554679d776575 100644
--- a/x-pack/plugins/reporting/kibana.json
+++ b/x-pack/plugins/reporting/kibana.json
@@ -25,5 +25,5 @@
],
"server": true,
"ui": true,
- "requiredBundles": ["kibanaReact", "discover"]
+ "requiredBundles": ["kibanaReact", "kibanaUtils", "discover"]
}
diff --git a/x-pack/plugins/reporting/public/index.ts b/x-pack/plugins/reporting/public/index.ts
index fdd5769ab3e00..e330bef849be4 100644
--- a/x-pack/plugins/reporting/public/index.ts
+++ b/x-pack/plugins/reporting/public/index.ts
@@ -5,7 +5,8 @@
* 2.0.
*/
-import { PluginInitializerContext } from 'src/core/public';
+import { PluginInitializerContext, ThemeServiceStart } from 'src/core/public';
+import { createGetterSetter } from '../../../../src/plugins/kibana_utils/public';
import { ReportingAPIClient } from './lib/reporting_api_client';
import { ReportingPublicPlugin } from './plugin';
import { getSharedComponents } from './shared';
@@ -27,3 +28,5 @@ export { ReportingAPIClient, ReportingPublicPlugin as Plugin };
export function plugin(initializerContext: PluginInitializerContext): ReportingPublicPlugin {
return new ReportingPublicPlugin(initializerContext);
}
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/x-pack/plugins/reporting/public/notifier/general_error.tsx b/x-pack/plugins/reporting/public/notifier/general_error.tsx
index 141b7b49444b0..b81940efc96c3 100644
--- a/x-pack/plugins/reporting/public/notifier/general_error.tsx
+++ b/x-pack/plugins/reporting/public/notifier/general_error.tsx
@@ -10,6 +10,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
+import { getTheme } from '..';
export const getGeneralErrorToast = (errorText: string, err: Error): ToastInput => ({
text: toMountPoint(
@@ -24,7 +25,8 @@ export const getGeneralErrorToast = (errorText: string, err: Error): ToastInput
id="xpack.reporting.publicNotifier.error.tryRefresh"
defaultMessage="Try refreshing the page."
/>
-
+ ,
+ { theme$: getTheme().theme$ }
),
iconType: undefined,
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_failure.tsx b/x-pack/plugins/reporting/public/notifier/job_failure.tsx
index a9e7b78c7e12f..2f305e19f7e62 100644
--- a/x-pack/plugins/reporting/public/notifier/job_failure.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_failure.tsx
@@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
import { ToastInput } from 'src/core/public';
+import { getTheme } from '..';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobSummary, ManagementLinkFn } from '../../common/types';
@@ -24,7 +25,8 @@ export const getFailureToast = (
id="xpack.reporting.publicNotifier.error.couldNotCreateReportTitle"
defaultMessage="Could not create report for {reportObjectType} '{reportObjectTitle}'."
values={{ reportObjectType: job.jobtype, reportObjectTitle: job.title }}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
text: toMountPoint(
@@ -58,7 +60,8 @@ export const getFailureToast = (
}}
/>
-
+ ,
+ { theme$: getTheme().theme$ }
),
iconType: undefined,
'data-test-subj': 'completeReportFailure',
diff --git a/x-pack/plugins/reporting/public/notifier/job_success.tsx b/x-pack/plugins/reporting/public/notifier/job_success.tsx
index c1de9a7625858..92f9d2f206616 100644
--- a/x-pack/plugins/reporting/public/notifier/job_success.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_success.tsx
@@ -8,6 +8,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
import { ToastInput } from 'src/core/public';
+import { getTheme } from '..';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -23,7 +24,8 @@ export const getSuccessToast = (
id="xpack.reporting.publicNotifier.successfullyCreatedReportNotificationTitle"
defaultMessage="Created report for {reportObjectType} '{reportObjectTitle}'"
values={{ reportObjectType: job.jobtype, reportObjectTitle: job.title }}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
color: 'success',
text: toMountPoint(
@@ -32,7 +34,8 @@ export const getSuccessToast = (
-
+ ,
+ { theme$: getTheme().theme$ }
),
'data-test-subj': 'completeReportSuccess',
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx b/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
index c835203813b86..8dde77afa8011 100644
--- a/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
@@ -8,6 +8,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
import { ToastInput } from 'src/core/public';
+import { getTheme } from '..';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -23,7 +24,8 @@ export const getWarningFormulasToast = (
id="xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportTitle"
defaultMessage="Report may contain formulas {reportObjectType} '{reportObjectTitle}'"
values={{ reportObjectType: job.jobtype, reportObjectTitle: job.title }}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
text: toMountPoint(
@@ -37,7 +39,8 @@ export const getWarningFormulasToast = (
-
+ ,
+ { theme$: getTheme().theme$ }
),
'data-test-subj': 'completeReportCsvFormulasWarning',
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx b/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
index f7cc8e2219df9..24ab6b0945bed 100644
--- a/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
@@ -8,6 +8,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
import { ToastInput } from 'src/core/public';
+import { getTheme } from '..';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -23,7 +24,8 @@ export const getWarningMaxSizeToast = (
id="xpack.reporting.publicNotifier.maxSizeReached.partialReportTitle"
defaultMessage="Created partial report for {reportObjectType} '{reportObjectTitle}'"
values={{ reportObjectType: job.jobtype, reportObjectTitle: job.title }}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
text: toMountPoint(
@@ -37,7 +39,8 @@ export const getWarningMaxSizeToast = (
-
+ ,
+ { theme$: getTheme().theme$ }
),
'data-test-subj': 'completeReportMaxSizeWarning',
});
diff --git a/x-pack/plugins/reporting/public/plugin.ts b/x-pack/plugins/reporting/public/plugin.ts
index b1f9b63e66cbe..e6db6be1ab16f 100644
--- a/x-pack/plugins/reporting/public/plugin.ts
+++ b/x-pack/plugins/reporting/public/plugin.ts
@@ -29,7 +29,7 @@ import { ManagementSetup, ManagementStart } from '../../../../src/plugins/manage
import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/public';
import { durationToNumber } from '../common/schema_utils';
import { JobId, JobSummarySet } from '../common/types';
-import { ReportingSetup, ReportingStart } from './';
+import { ReportingSetup, ReportingStart, setTheme } from './';
import { ReportingAPIClient } from './lib/reporting_api_client';
import { ReportingNotifierStreamHandler as StreamHandler } from './lib/stream_handler';
import { getGeneralErrorToast } from './notifier';
@@ -158,6 +158,7 @@ export class ReportingPublicPlugin
const startServices$ = Rx.from(getStartServices());
const usesUiCapabilities = !this.config.roles.enabled;
+ setTheme(core.theme);
const apiClient = this.getApiClient(core.http, core.uiSettings);
diff --git a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
index 73ccbc2b13d75..dc7ea454689e5 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
@@ -20,6 +20,7 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n-react';
import React, { Component, ReactElement } from 'react';
import { IUiSettingsClient, ToastsSetup } from 'src/core/public';
import url from 'url';
+import { getTheme } from '../..';
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
import {
CSV_REPORT_TYPE,
@@ -291,7 +292,8 @@ class ReportingPanelContentUi extends Component {
),
}}
- />
+ />,
+ { theme$: getTheme().theme$ }
),
'data-test-subj': 'queueReportSuccess',
});
diff --git a/x-pack/plugins/reporting/tsconfig.json b/x-pack/plugins/reporting/tsconfig.json
index 4e09708915f95..cb22a7d9e719a 100644
--- a/x-pack/plugins/reporting/tsconfig.json
+++ b/x-pack/plugins/reporting/tsconfig.json
@@ -6,18 +6,14 @@
"declaration": true,
"declarationMap": true
},
- "include": [
- "common/**/*",
- "public/**/*",
- "server/**/*",
- "../../../typings/**/*"
- ],
+ "include": ["common/**/*", "public/**/*", "server/**/*", "../../../typings/**/*"],
"references": [
{ "path": "../../../src/core/tsconfig.json" },
- { "path": "../../../src/plugins/data/tsconfig.json"},
+ { "path": "../../../src/plugins/data/tsconfig.json" },
{ "path": "../../../src/plugins/discover/tsconfig.json" },
{ "path": "../../../src/plugins/embeddable/tsconfig.json" },
{ "path": "../../../src/plugins/kibana_react/tsconfig.json" },
+ { "path": "../../../src/plugins/kibana_utils/tsconfig.json" },
{ "path": "../../../src/plugins/management/tsconfig.json" },
{ "path": "../../../src/plugins/screenshot_mode/tsconfig.json" },
{ "path": "../../../src/plugins/share/tsconfig.json" },
@@ -28,6 +24,6 @@
{ "path": "../licensing/tsconfig.json" },
{ "path": "../screenshotting/tsconfig.json" },
{ "path": "../security/tsconfig.json" },
- { "path": "../spaces/tsconfig.json" },
+ { "path": "../spaces/tsconfig.json" }
]
}
diff --git a/x-pack/plugins/runtime_fields/README.md b/x-pack/plugins/runtime_fields/README.md
index eb7b31e6e1154..9c0e0e03f2fe5 100644
--- a/x-pack/plugins/runtime_fields/README.md
+++ b/x-pack/plugins/runtime_fields/README.md
@@ -72,7 +72,7 @@ interface RuntimeField {
type: RuntimeType; // 'long' | 'boolean' ...
script: {
source: string;
- }
+ };
}
```
@@ -103,8 +103,8 @@ interface Context {
The runtime field editor is also exported as static React component that you can import into your components. The editor is exported in 2 flavours:
-* As the content of a `` (it contains a flyout header and footer)
-* As a standalone component that you can inline anywhere
+- As the content of a `` (it contains a flyout header and footer)
+- As a standalone component that you can inline anywhere
**Note:** The runtime field editor uses the `` that has a dependency on the `Provider` from the `"kibana_react"` plugin. If your app is not already wrapped by this provider you will need to add it at least around the runtime field editor. You can see an example in the ["Using the core.overlays.openFlyout()"](#using-the-coreoverlaysopenflyout) example below.
@@ -118,7 +118,7 @@ import { RuntimeFieldEditorFlyoutContent, RuntimeField } from '../runtime_fields
const MyComponent = () => {
const { docLinksStart } = useCoreContext(); // access the core start service
const [isFlyoutVisilbe, setIsFlyoutVisible] = useState(false);
-
+
const saveRuntimeField = useCallback((field: RuntimeField) => {
// Do something with the field
}, []);
@@ -139,7 +139,7 @@ const MyComponent = () => {
)}
>
- )
+ )
}
```
@@ -157,11 +157,11 @@ import { RuntimeFieldEditorFlyoutContent, RuntimeField } from '../runtime_fields
const MyComponent = () => {
// Access the core start service
- const { docLinksStart, overlays, uiSettings } = useCoreContext();
+ const { docLinksStart, theme, overlays, uiSettings } = useCoreContext();
const flyoutEditor = useRef(null);
const { openFlyout } = overlays;
-
+
const saveRuntimeField = useCallback((field: RuntimeField) => {
// Do something with the field
}, []);
@@ -179,7 +179,8 @@ const MyComponent = () => {
defaultValue={defaultRuntimeField}
ctx={/*optional context object -- see section above*/}
/>
-
+ ,
+ { theme$: theme.theme$ }
)
);
}, [openFlyout, saveRuntimeField, uiSettings]);
@@ -188,7 +189,7 @@ const MyComponent = () => {
<>
Create field
>
- )
+ )
}
```
@@ -208,7 +209,7 @@ const MyComponent = () => {
});
const { submit, isValid: isFormValid, isSubmitted } = runtimeFieldFormState;
-
+
const saveRuntimeField = useCallback(async () => {
const { isValid, data } = await submit();
if (isValid) {
@@ -233,6 +234,6 @@ const MyComponent = () => {
Save field
>
- )
+ )
}
-```
\ No newline at end of file
+```
diff --git a/x-pack/plugins/runtime_fields/public/load_editor.tsx b/x-pack/plugins/runtime_fields/public/load_editor.tsx
index 0cea90f33a54d..6aec33b90466f 100644
--- a/x-pack/plugins/runtime_fields/public/load_editor.tsx
+++ b/x-pack/plugins/runtime_fields/public/load_editor.tsx
@@ -22,7 +22,7 @@ export const getRuntimeFieldEditorLoader =
(coreSetup: CoreSetup) => async (): Promise => {
const { RuntimeFieldEditorFlyoutContent } = await import('./components');
const [core] = await coreSetup.getStartServices();
- const { uiSettings, overlays, docLinks } = core;
+ const { uiSettings, theme, overlays, docLinks } = core;
const { Provider: KibanaReactContextProvider } = createKibanaReactContext({ uiSettings });
let overlayRef: OverlayRef | null = null;
@@ -50,7 +50,8 @@ export const getRuntimeFieldEditorLoader =
defaultValue={defaultValue}
ctx={ctx}
/>
-
+ ,
+ { theme$: theme.theme$ }
)
);
From 26bb5fcd17457f659bee33f2bafa375e15720865 Mon Sep 17 00:00:00 2001
From: shivindera
Date: Thu, 6 Jan 2022 12:00:58 +0100
Subject: [PATCH 3/7] build fixes and jest fixes part 1
---
.../dashboard_listing.test.tsx.snap | 56 +++++++++++++++++++
src/plugins/data_views/public/plugin.ts | 5 +-
x-pack/examples/reporting_example/kibana.json | 9 ++-
.../examples/reporting_example/tsconfig.json | 6 +-
4 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap
index 2f383adb3f5c3..598254ad2173f 100644
--- a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap
+++ b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap
@@ -96,6 +96,14 @@ exports[`after fetch When given a title that matches multiple dashboards, filter
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -208,6 +216,14 @@ exports[`after fetch initialFilter 1`] = `
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -319,6 +335,14 @@ exports[`after fetch renders all table rows 1`] = `
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -430,6 +454,14 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = `
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -552,6 +584,14 @@ exports[`after fetch renders call to action with continue when no dashboards exi
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -663,6 +703,14 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
@@ -744,6 +792,14 @@ exports[`after fetch showWriteControls 1`] = `
]
}
tableListTitle="Dashboards"
+ theme={
+ Object {
+ "theme$": Observable {
+ "_isScalar": false,
+ "_subscribe": [Function],
+ },
+ }
+ }
toastNotifications={
Object {
"add": [MockFunction],
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index 4a00ea91a47bd..bf092d3fae177 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -45,7 +45,7 @@ export class DataViewsPublicPlugin
core: CoreStart,
{ fieldFormats }: DataViewsPublicStartDependencies
): DataViewsPublicPluginStart {
- const { uiSettings, http, notifications, savedObjects, overlays, application } = core;
+ const { uiSettings, http, notifications, savedObjects, theme, overlays, application } = core;
return new DataViewsService({
uiSettings: new UiSettingsPublicToCommon(uiSettings),
@@ -59,7 +59,8 @@ export class DataViewsPublicPlugin
onRedirectNoIndexPattern: onRedirectNoIndexPattern(
application.capabilities,
application.navigateToApp,
- overlays
+ overlays,
+ theme
),
getCanSave: () => Promise.resolve(application.capabilities.indexPatterns.save === true),
});
diff --git a/x-pack/examples/reporting_example/kibana.json b/x-pack/examples/reporting_example/kibana.json
index 94780f1df0b36..489b2bcd9f506 100644
--- a/x-pack/examples/reporting_example/kibana.json
+++ b/x-pack/examples/reporting_example/kibana.json
@@ -10,6 +10,13 @@
},
"description": "Example integration code for applications to feature reports.",
"optionalPlugins": [],
- "requiredPlugins": ["reporting", "developerExamples", "navigation", "screenshotMode", "share"],
+ "requiredPlugins": [
+ "reporting",
+ "developerExamples",
+ "kibanaReact",
+ "navigation",
+ "screenshotMode",
+ "share"
+ ],
"requiredBundles": ["screenshotting"]
}
diff --git a/x-pack/examples/reporting_example/tsconfig.json b/x-pack/examples/reporting_example/tsconfig.json
index 4c4016911e0c5..1b097d8e52868 100644
--- a/x-pack/examples/reporting_example/tsconfig.json
+++ b/x-pack/examples/reporting_example/tsconfig.json
@@ -9,15 +9,15 @@
"public/**/*.tsx",
"server/**/*.ts",
"common/**/*.ts",
- "../../../typings/**/*",
+ "../../../typings/**/*"
],
"exclude": [],
"references": [
{ "path": "../../../src/core/tsconfig.json" },
+ { "path": "../../../src/plugins/kibana_react/tsconfig.json" },
{ "path": "../../../src/plugins/navigation/tsconfig.json" },
{ "path": "../../../src/plugins/screenshot_mode/tsconfig.json" },
{ "path": "../../../examples/developer_examples/tsconfig.json" },
- { "path": "../../plugins/reporting/tsconfig.json" },
+ { "path": "../../plugins/reporting/tsconfig.json" }
]
}
-
From 08a6918c866c398ecd7dcd1a4b22e830b6471aae Mon Sep 17 00:00:00 2001
From: shivindera
Date: Thu, 6 Jan 2022 16:30:25 +0100
Subject: [PATCH 4/7] jest fixes part 2
---
.../public/actions/apply_filter_action.ts | 8 +-
src/plugins/data/public/plugin.ts | 4 +-
.../search/fetch/handle_response.test.ts | 9 +-
.../public/search/fetch/handle_response.tsx | 18 +++-
.../search_interceptor.test.ts | 3 +-
.../search_interceptor/search_interceptor.ts | 12 +--
.../data/public/search/search_service.ts | 10 +-
src/plugins/data/public/services.ts | 4 +-
.../query_string_input/query_bar_top_row.tsx | 3 +
.../query_string_input/query_string_input.tsx | 6 +-
.../ui/search_bar/create_search_bar.tsx | 1 +
.../data/public/ui/search_bar/search_bar.tsx | 3 +
.../shard_failure_open_modal_button.test.tsx | 4 +
.../shard_failure_open_modal_button.tsx | 7 +-
.../lib/embeddables/error_embeddable.tsx | 44 +++++---
src/plugins/embeddable/public/plugin.tsx | 1 +
.../adapters/ui_to_react_component.test.tsx | 89 +++------------
.../public/context/context.test.tsx | 96 +++++++----------
.../ui_settings/use_ui_setting.test.tsx | 53 ++++-----
...ate_state_container_react_helpers.test.tsx | 101 +++++++-----------
.../components/visualize_listing.tsx | 4 +-
.../visualize/public/application/types.ts | 2 +
.../public/application/utils/utils.ts | 3 +-
src/plugins/visualize/public/plugin.ts | 2 -
src/plugins/visualize/public/services.ts | 4 +-
x-pack/plugins/reporting/kibana.json | 2 +-
x-pack/plugins/reporting/public/index.ts | 5 +-
.../public/lib/stream_handler.test.ts | 20 ++--
.../reporting/public/lib/stream_handler.ts | 26 +++--
.../public/notifier/general_error.tsx | 11 +-
.../reporting/public/notifier/job_failure.tsx | 10 +-
.../reporting/public/notifier/job_success.tsx | 10 +-
.../public/notifier/job_warning_formulas.tsx | 10 +-
.../public/notifier/job_warning_max_size.tsx | 10 +-
x-pack/plugins/reporting/public/plugin.ts | 19 ++--
.../public/share_context_menu/index.ts | 3 +-
.../register_csv_reporting.tsx | 2 +
.../register_pdf_png_reporting.tsx | 3 +
.../reporting_panel_content.test.tsx | 4 +
.../reporting_panel_content.tsx | 6 +-
.../screen_capture_panel_content.test.tsx | 10 +-
.../public/shared/get_shared_components.tsx | 3 +
.../runtime_fields/public/plugin.test.ts | 3 +-
43 files changed, 298 insertions(+), 350 deletions(-)
diff --git a/src/plugins/data/public/actions/apply_filter_action.ts b/src/plugins/data/public/actions/apply_filter_action.ts
index d84e58856d3e6..97e332dfa01f0 100644
--- a/src/plugins/data/public/actions/apply_filter_action.ts
+++ b/src/plugins/data/public/actions/apply_filter_action.ts
@@ -7,9 +7,10 @@
*/
import { i18n } from '@kbn/i18n';
+import { ThemeServiceSetup } from 'kibana/public';
import { toMountPoint } from '../../../kibana_react/public';
import { Action, createAction, IncompatibleActionError } from '../../../ui_actions/public';
-import { getOverlays, getTheme, getIndexPatterns } from '../services';
+import { getOverlays, getIndexPatterns } from '../services';
import { applyFiltersPopover } from '../ui/apply_filters';
import { Filter, FilterManager, TimefilterContract, esFilters } from '..';
@@ -32,7 +33,8 @@ async function isCompatible(context: ApplyGlobalFilterActionContext) {
export function createFilterAction(
filterManager: FilterManager,
- timeFilter: TimefilterContract
+ timeFilter: TimefilterContract,
+ theme: ThemeServiceSetup
): Action {
return createAction({
type: ACTION_GLOBAL_APPLY_FILTER,
@@ -78,7 +80,7 @@ export function createFilterAction(
resolve(filterSelection);
}
),
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
{
'data-test-subj': 'test',
diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts
index 5e46b74fab809..9e0fae0053378 100644
--- a/src/plugins/data/public/plugin.ts
+++ b/src/plugins/data/public/plugin.ts
@@ -26,7 +26,6 @@ import {
setNotifications,
setOverlays,
setSearchService,
- setTheme,
setUiSettings,
} from './services';
import { createSearchBar } from './ui/search_bar/create_search_bar';
@@ -83,7 +82,6 @@ export class DataPublicPlugin
const startServices = createStartServicesGetter(core.getStartServices);
this.usageCollection = usageCollection;
- setTheme(core.theme);
const searchService = this.searchService.setup(core, {
bfetch,
@@ -100,7 +98,7 @@ export class DataPublicPlugin
uiActions.registerTrigger(applyFilterTrigger);
uiActions.registerAction(
- createFilterAction(queryService.filterManager, queryService.timefilter.timefilter)
+ createFilterAction(queryService.filterManager, queryService.timefilter.timefilter, core.theme)
);
inspector.registerView(
diff --git a/src/plugins/data/public/search/fetch/handle_response.test.ts b/src/plugins/data/public/search/fetch/handle_response.test.ts
index 1a430f860f438..f79ab8e9c16fe 100644
--- a/src/plugins/data/public/search/fetch/handle_response.test.ts
+++ b/src/plugins/data/public/search/fetch/handle_response.test.ts
@@ -13,6 +13,7 @@ import { handleResponse } from './handle_response';
import { notificationServiceMock } from '../../../../../core/public/notifications/notifications_service.mock';
import { setNotifications } from '../../services';
import { IKibanaSearchResponse } from 'src/plugins/data/common';
+import { themeServiceMock } from 'src/core/public/mocks';
jest.mock('@kbn/i18n', () => {
return {
@@ -22,6 +23,8 @@ jest.mock('@kbn/i18n', () => {
};
});
+const theme = themeServiceMock.createStartContract();
+
describe('handleResponse', () => {
const notifications = notificationServiceMock.createStartContract();
@@ -37,7 +40,7 @@ describe('handleResponse', () => {
timed_out: true,
},
} as IKibanaSearchResponse;
- const result = handleResponse(request, response);
+ const result = handleResponse(request, response, theme);
expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled();
expect((notifications.toasts.addWarning as jest.Mock).mock.calls[0][0].title).toMatch(
@@ -57,7 +60,7 @@ describe('handleResponse', () => {
},
},
} as IKibanaSearchResponse;
- const result = handleResponse(request, response);
+ const result = handleResponse(request, response, theme);
expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled();
expect((notifications.toasts.addWarning as jest.Mock).mock.calls[0][0].title).toMatch(
@@ -70,7 +73,7 @@ describe('handleResponse', () => {
const response = {
rawResponse: {},
} as IKibanaSearchResponse;
- const result = handleResponse(request, response);
+ const result = handleResponse(request, response, theme);
expect(result).toBe(response);
});
});
diff --git a/src/plugins/data/public/search/fetch/handle_response.tsx b/src/plugins/data/public/search/fetch/handle_response.tsx
index 7eaa745cce986..618efcb702ec4 100644
--- a/src/plugins/data/public/search/fetch/handle_response.tsx
+++ b/src/plugins/data/public/search/fetch/handle_response.tsx
@@ -11,11 +11,16 @@ import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
import { IKibanaSearchResponse } from 'src/plugins/data/common';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
+import { ThemeServiceStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
-import { getNotifications, getTheme } from '../../services';
+import { getNotifications } from '../../services';
import type { SearchRequest } from '..';
-export function handleResponse(request: SearchRequest, response: IKibanaSearchResponse) {
+export function handleResponse(
+ request: SearchRequest,
+ response: IKibanaSearchResponse,
+ theme: ThemeServiceStart
+) {
const { rawResponse } = response;
if (rawResponse.timed_out) {
@@ -45,9 +50,14 @@ export function handleResponse(request: SearchRequest, response: IKibanaSearchRe
<>
{description}
-
+
>,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
);
getNotifications().toasts.addWarning({ title, text });
diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts
index 142fa94c96162..968dd870489fe 100644
--- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts
+++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts
@@ -8,7 +8,7 @@
import type { MockedKeys } from '@kbn/utility-types/jest';
import { CoreSetup, CoreStart } from '../../../../../core/public';
-import { coreMock } from '../../../../../core/public/mocks';
+import { coreMock, themeServiceMock } from '../../../../../core/public/mocks';
import { IEsSearchRequest } from '../../../common/search';
import { SearchInterceptor } from './search_interceptor';
import { AbortError } from '../../../../kibana_utils/public';
@@ -120,6 +120,7 @@ describe('SearchInterceptor', () => {
uiSettings: mockCoreSetup.uiSettings,
http: mockCoreSetup.http,
session: sessionService,
+ theme: themeServiceMock.createSetupContract(),
});
});
diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
index 244f0e065f9df..8c7bfe68fd54b 100644
--- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
+++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts
@@ -21,7 +21,7 @@ import {
tap,
} from 'rxjs/operators';
import { PublicMethodsOf } from '@kbn/utility-types';
-import { CoreSetup, CoreStart, ToastsSetup } from 'kibana/public';
+import { CoreSetup, CoreStart, ThemeServiceSetup, ToastsSetup } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { BatchedFunc, BfetchPublicSetup } from 'src/plugins/bfetch/public';
import {
@@ -51,7 +51,6 @@ import { ISessionService, SearchSessionState } from '../session';
import { SearchResponseCache } from './search_response_cache';
import { createRequestHash } from './utils';
import { SearchAbortController } from './search_abort_controller';
-import { getTheme } from '../../services';
export interface SearchInterceptorDeps {
bfetch: BfetchPublicSetup;
@@ -61,6 +60,7 @@ export interface SearchInterceptorDeps {
toasts: ToastsSetup;
usageCollector?: SearchUsageCollector;
session: ISessionService;
+ theme: ThemeServiceSetup;
}
const MAX_CACHE_ITEMS = 50;
@@ -378,7 +378,7 @@ export class SearchInterceptor {
private showTimeoutErrorToast = (e: SearchTimeoutError, sessionId?: string) => {
this.deps.toasts.addDanger({
title: 'Timed out',
- text: toMountPoint(e.getErrorMessage(this.application), { theme$: getTheme().theme$ }),
+ text: toMountPoint(e.getErrorMessage(this.application), { theme$: this.deps.theme.theme$ }),
});
};
@@ -394,7 +394,7 @@ export class SearchInterceptor {
{
title: 'Your search session is still running',
text: toMountPoint(SearchSessionIncompleteWarning(this.docLinks), {
- theme$: getTheme().theme$,
+ theme$: this.deps.theme.theme$,
}),
},
{
@@ -426,14 +426,14 @@ export class SearchInterceptor {
title: i18n.translate('data.search.esErrorTitle', {
defaultMessage: 'Cannot retrieve search results',
}),
- text: toMountPoint(e.getErrorMessage(this.application), { theme$: getTheme().theme$ }),
+ text: toMountPoint(e.getErrorMessage(this.application), { theme$: this.deps.theme.theme$ }),
});
} else if (e.constructor.name === 'HttpFetchError') {
this.deps.toasts.addDanger({
title: i18n.translate('data.search.httpErrorTitle', {
defaultMessage: 'Cannot retrieve your data',
}),
- text: toMountPoint(getHttpError(e.message), { theme$: getTheme().theme$ }),
+ text: toMountPoint(getHttpError(e.message), { theme$: this.deps.theme.theme$ }),
});
} else {
this.deps.toasts.addError(e, {
diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts
index 76aae8582287d..311a863a74933 100644
--- a/src/plugins/data/public/search/search_service.ts
+++ b/src/plugins/data/public/search/search_service.ts
@@ -46,7 +46,7 @@ import {
esRawResponse,
} from '../../common/search';
import { AggsService, AggsStartDependencies } from './aggs';
-import { IndexPatternsContract } from '..';
+import { IKibanaSearchResponse, IndexPatternsContract, SearchRequest } from '..';
import { ISearchInterceptor, SearchInterceptor } from './search_interceptor';
import { SearchUsageCollector, createUsageCollector } from './collectors';
import { UsageCollectionSetup } from '../../../usage_collection/public';
@@ -88,7 +88,7 @@ export class SearchService implements Plugin {
constructor(private initializerContext: PluginInitializerContext) {}
public setup(
- { http, getStartServices, notifications, uiSettings }: CoreSetup,
+ { http, getStartServices, notifications, uiSettings, theme }: CoreSetup,
{ bfetch, expressions, usageCollection, nowProvider }: SearchServiceSetupDependencies
): ISearchSetup {
this.usageCollector = createUsageCollector(getStartServices, usageCollection);
@@ -112,6 +112,7 @@ export class SearchService implements Plugin {
startServices: getStartServices(),
usageCollector: this.usageCollector!,
session: this.sessionService,
+ theme,
});
expressions.registerFunction(
@@ -173,7 +174,7 @@ export class SearchService implements Plugin {
}
public start(
- { http, uiSettings }: CoreStart,
+ { http, theme, uiSettings }: CoreStart,
{ fieldFormats, indexPatterns }: SearchServiceStartDependencies
): ISearchStart {
const search = ((request, options = {}) => {
@@ -186,7 +187,8 @@ export class SearchService implements Plugin {
const searchSourceDependencies: SearchSourceDependencies = {
getConfig: uiSettings.get.bind(uiSettings),
search,
- onResponse: handleResponse,
+ onResponse: (request: SearchRequest, response: IKibanaSearchResponse) =>
+ handleResponse(request, response, theme),
};
return {
diff --git a/src/plugins/data/public/services.ts b/src/plugins/data/public/services.ts
index 5c52a1e695359..c1a0ae1ac1b53 100644
--- a/src/plugins/data/public/services.ts
+++ b/src/plugins/data/public/services.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { NotificationsStart, CoreStart, ThemeServiceStart } from 'src/core/public';
+import { NotificationsStart, CoreStart } from 'src/core/public';
import { createGetterSetter } from '../../kibana_utils/public';
import { IndexPatternsContract } from './data_views';
import { DataPublicPluginStart } from './types';
@@ -24,5 +24,3 @@ export const [getIndexPatterns, setIndexPatterns] =
export const [getSearchService, setSearchService] =
createGetterSetter('Search');
-
-export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
index 76d4b9dd8e801..04763c209c61b 100644
--- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
@@ -20,6 +20,7 @@ import {
} from '@elastic/eui';
// @ts-ignore
import { EuiSuperUpdateButton, OnRefreshProps } from '@elastic/eui';
+import { ThemeServiceStart } from 'kibana/public';
import { IDataPluginServices, IIndexPattern, TimeRange, TimeHistoryContract, Query } from '../..';
import { useKibana, withKibana } from '../../../../kibana_react/public';
import QueryStringInputUI from './query_string_input';
@@ -61,6 +62,7 @@ export interface QueryBarTopRowProps {
showAutoRefreshOnly?: boolean;
timeHistory?: TimeHistoryContract;
timeRangeForSuggestionsOverride?: boolean;
+ theme: ThemeServiceStart;
}
// Needed for React.lazy
@@ -192,6 +194,7 @@ export default function QueryBarTopRow(props: QueryBarTopRowProps) {
nonKqlMode={props.nonKqlMode}
nonKqlModeHelpText={props.nonKqlModeHelpText}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
+ theme={props.theme}
/>
);
diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
index bfc1cad560bb9..3585b3e54fdda 100644
--- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
@@ -26,7 +26,7 @@ import {
import { FormattedMessage } from '@kbn/i18n-react';
import { debounce, compact, isEqual, isFunction } from 'lodash';
-import { Toast } from 'src/core/public';
+import { ThemeServiceStart, Toast } from 'src/core/public';
import { METRIC_TYPE } from '@kbn/analytics';
import { IDataPluginServices, IIndexPattern, Query } from '../..';
import { QuerySuggestion, QuerySuggestionTypes } from '../../autocomplete';
@@ -39,7 +39,6 @@ import type { PersistedLog } from '../../query';
import type { SuggestionsListSize } from '../typeahead/suggestions_component';
import { SuggestionsComponent } from '..';
import { KIBANA_USER_QUERY_LANGUAGE_KEY, getFieldSubtypeNested } from '../../../common';
-import { getTheme } from '../../services';
export interface QueryStringInputProps {
indexPatterns: Array;
@@ -83,6 +82,7 @@ export interface QueryStringInputProps {
* Override whether autocomplete suggestions are restricted by time range.
*/
timeRangeForSuggestionsOverride?: boolean;
+ theme: ThemeServiceStart;
}
interface Props extends QueryStringInputProps {
@@ -477,7 +477,7 @@ export default class QueryStringInputUI extends Component {
,
- { theme$: getTheme().theme$ }
+ { theme$: this.props.theme.theme$ }
),
});
}
diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
index fda6a74e4b500..3da2e7f4093cd 100644
--- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
+++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
@@ -197,6 +197,7 @@ export function createSearchBar({ core, storage, data, usageCollection }: Statef
isClearable={props.isClearable}
placeholder={props.placeholder}
{...overrideDefaultBehaviors(props)}
+ theme={core.theme}
/>
);
diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx
index 87b6480096551..d60718124dc1a 100644
--- a/src/plugins/data/public/ui/search_bar/search_bar.tsx
+++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx
@@ -15,6 +15,7 @@ import { EuiIconProps } from '@elastic/eui';
import { METRIC_TYPE } from '@kbn/analytics';
import { Query, Filter } from '@kbn/es-query';
+import { ThemeServiceStart } from 'kibana/public';
import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public';
import QueryBarTopRow from '../query_string_input/query_bar_top_row';
@@ -79,6 +80,7 @@ export interface SearchBarOwnProps {
displayStyle?: 'inPage' | 'detached';
// super update button background fill control
fillSubmitButton?: boolean;
+ theme: ThemeServiceStart;
}
export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps;
@@ -391,6 +393,7 @@ class SearchBarUI extends Component {
nonKqlMode={this.props.nonKqlMode}
nonKqlModeHelpText={this.props.nonKqlModeHelpText}
timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride}
+ theme={this.props.theme}
/>
);
}
diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.test.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.test.tsx
index 28822cbd71ca7..b8289bc23cf01 100644
--- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.test.tsx
+++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.test.tsx
@@ -8,18 +8,22 @@
import { openModal } from './shard_failure_open_modal_button.test.mocks';
import React from 'react';
+import { themeServiceMock } from 'src/core/public/mocks';
import { mountWithIntl } from '@kbn/test/jest';
import ShardFailureOpenModalButton from './shard_failure_open_modal_button';
import { shardFailureRequest } from './__mocks__/shard_failure_request';
import { shardFailureResponse } from './__mocks__/shard_failure_response';
import { findTestSubject } from '@elastic/eui/lib/test';
+const theme = themeServiceMock.createStartContract();
+
describe('ShardFailureOpenModalButton', () => {
it('triggers the openModal function when "Show details" button is clicked', () => {
const component = mountWithIntl(
);
diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
index c8a217015d356..585268824fb93 100644
--- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
+++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
@@ -11,7 +11,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButton, EuiTextAlign } from '@elastic/eui';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { getOverlays, getTheme } from '../../services';
+import { getOverlays } from '../../services';
+import { ThemeServiceStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
import { ShardFailureModal } from './shard_failure_modal';
import { ShardFailureRequest } from './shard_failure_types';
@@ -20,6 +21,7 @@ import { ShardFailureRequest } from './shard_failure_types';
export interface ShardFailureOpenModalButtonProps {
request: ShardFailureRequest;
response: estypes.SearchResponse;
+ theme: ThemeServiceStart;
title: string;
}
@@ -28,6 +30,7 @@ export interface ShardFailureOpenModalButtonProps {
export default function ShardFailureOpenModalButton({
request,
response,
+ theme,
title,
}: ShardFailureOpenModalButtonProps) {
function onClick() {
@@ -39,7 +42,7 @@ export default function ShardFailureOpenModalButton({
title={title}
onClose={() => modal.close()}
/>,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
{
className: 'shardFailureModal',
diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
index ab8551500adbf..7f10776e75653 100644
--- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
@@ -38,24 +38,34 @@ export class ErrorEmbeddable extends Embeddable
- // @ts-ignore
-
-
-
-
-
-
-
- ,
- ,
- dom
+ let theme;
+ try {
+ theme = getTheme();
+ } catch (err) {
+ theme = {};
+ }
+ // @ts-ignore
+ const node = (
+
+
+
+
+
+
+
);
+ const content =
+ theme && theme.theme$ ? (
+ {node}
+ ) : (
+ node
+ );
+
+ ReactDOM.render(content, dom);
}
public destroy() {
diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx
index 9c9574651ff1d..e78937a9caebd 100644
--- a/src/plugins/embeddable/public/plugin.tsx
+++ b/src/plugins/embeddable/public/plugin.tsx
@@ -149,6 +149,7 @@ export class EmbeddablePublicPlugin implements Plugin {
this.appList = appList;
diff --git a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
index 89a41e1d57461..0a435f89bff37 100644
--- a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
+++ b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx
@@ -8,14 +8,9 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
-import { ThemeServiceStart } from '../../../../core/public';
-import { themeServiceMock } from '../../../../core/public/mocks';
import { UiComponent } from '../../../kibana_utils/public';
import { uiToReactComponent } from './ui_to_react_component';
import { reactToUiComponent } from './react_to_ui_component';
-import { KibanaThemeProvider } from '..';
-
-const theme: ThemeServiceStart = themeServiceMock.createStartContract();
const UiComp: UiComponent<{ cnt?: number }> = () => ({
render: (el, { cnt = 0 }) => {
@@ -29,12 +24,7 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.innerHTML).toBe('cnt: 0
');
});
@@ -43,12 +33,7 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.innerHTML).toBe('cnt: 5
');
});
@@ -57,21 +42,11 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp);
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.innerHTML).toBe('cnt: 1
');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.innerHTML).toBe('cnt: 2
');
});
@@ -86,12 +61,7 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp2);
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
ReactDOM.unmountComponentAtNode(div);
expect(div.innerHTML).toBe('');
@@ -111,12 +81,7 @@ describe('uiToReactComponent', () => {
expect(unmount).toHaveBeenCalledTimes(0);
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(unmount).toHaveBeenCalledTimes(0);
@@ -138,30 +103,15 @@ describe('uiToReactComponent', () => {
expect(render).toHaveBeenCalledTimes(0);
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(render).toHaveBeenCalledTimes(1);
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(render).toHaveBeenCalledTimes(2);
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(render).toHaveBeenCalledTimes(3);
});
@@ -170,12 +120,7 @@ describe('uiToReactComponent', () => {
const ReactComp = uiToReactComponent(UiComp, 'span');
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.innerHTML).toBe('cnt: 5');
});
@@ -187,21 +132,11 @@ test('can adapt component many times', () => {
);
const div = document.createElement('div');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.textContent).toBe('cnt: 0');
- ReactDOM.render(
-
-
- ,
- div
- );
+ ReactDOM.render(, div);
expect(div.textContent).toBe('cnt: 123');
});
diff --git a/src/plugins/kibana_react/public/context/context.test.tsx b/src/plugins/kibana_react/public/context/context.test.tsx
index 90d175b422bd1..a806f3eb66f75 100644
--- a/src/plugins/kibana_react/public/context/context.test.tsx
+++ b/src/plugins/kibana_react/public/context/context.test.tsx
@@ -9,12 +9,10 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { context, createKibanaReactContext, useKibana, KibanaContextProvider } from './context';
-import { CoreStart, ThemeServiceStart } from '../../../../core/public';
-import { coreMock, overlayServiceMock, themeServiceMock } from '../../../../core/public/mocks';
-import { KibanaThemeProvider } from '..';
+import { coreMock, overlayServiceMock } from '../../../../core/public/mocks';
+import { CoreStart } from '../../../../core/public';
let container: HTMLDivElement | null;
-const theme: ThemeServiceStart = themeServiceMock.createStartContract();
beforeEach(() => {
container = document.createElement('div');
@@ -29,11 +27,9 @@ afterEach(() => {
test('can mount without crashing', () => {
const services = coreMock.createStart();
ReactDOM.render(
-
-
- Hello world
-
- ,
+
+ Hello world
+ ,
container
);
});
@@ -47,11 +43,9 @@ test('useKibana() hook retrieves Kibana context', () => {
const core = coreMock.createStart();
(core as any).foo = 'bar';
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -66,11 +60,9 @@ test('createContext() creates context that can be consumed by useKibana() hook',
const { Provider } = createKibanaReactContext(services);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -91,11 +83,9 @@ test('services, notifications and overlays objects are always available', () =>
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
});
@@ -112,11 +102,9 @@ test(' provider provides default kibana-react context', (
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
});
@@ -129,11 +117,9 @@ test(' can set custom services in context', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
});
@@ -148,15 +134,13 @@ test('nested override and merge services', () => {
};
ReactDOM.render(
-
-
-
-
-
-
+
+
+
+
- ,
+ ,
container
);
});
@@ -178,13 +162,11 @@ test('overlays wrapper uses the closest overlays service', () => {
} as Partial;
ReactDOM.render(
-
-
-
-
-
+
+
+
- ,
+ ,
container
);
@@ -218,13 +200,11 @@ test('notifications wrapper uses the closest notifications service', () => {
} as Partial;
ReactDOM.render(
-
-
-
-
-
+
+
+
- ,
+ ,
container
);
@@ -259,13 +239,11 @@ test('overlays wrapper uses available overlays service, higher up in
-
-
-
-
+
+
+
- ,
+ ,
container
);
diff --git a/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx b/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
index d937388164b9d..44dea2aa420a7 100644
--- a/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
+++ b/src/plugins/kibana_react/public/ui_settings/use_ui_setting.test.tsx
@@ -13,15 +13,12 @@ import { useUiSetting$ } from './use_ui_setting';
import { createKibanaReactContext } from '../context';
import { KibanaServices } from '../context/types';
import { Subject } from 'rxjs';
-import { ThemeServiceStart } from '../../../../core/public';
-import { coreMock, themeServiceMock } from '../../../../core/public/mocks';
+import { coreMock } from '../../../../core/public/mocks';
import useObservable from 'react-use/lib/useObservable';
-import { KibanaThemeProvider } from '..';
jest.mock('react-use/lib/useObservable');
const useObservableSpy = useObservable as any as jest.SpyInstance;
useObservableSpy.mockImplementation((observable, def) => def);
-const theme: ThemeServiceStart = themeServiceMock.createStartContract();
const mock = (): [KibanaServices, Subject] => {
const core = coreMock.createStart();
@@ -68,11 +65,9 @@ describe('useUiSetting', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -87,11 +82,9 @@ describe('useUiSetting', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -121,11 +114,9 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -140,11 +131,9 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -158,11 +147,9 @@ describe('useUiSetting$', () => {
expect(useObservableSpy).toHaveBeenCalledTimes(0);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -175,11 +162,9 @@ describe('useUiSetting$', () => {
const { Provider } = createKibanaReactContext(core);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
diff --git a/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx b/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
index 79ce6b4015975..997a3710c58cb 100644
--- a/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
+++ b/src/plugins/kibana_utils/common/state_containers/create_state_container_react_helpers.test.tsx
@@ -11,13 +11,8 @@ import * as ReactDOM from 'react-dom';
import { act, Simulate } from 'react-dom/test-utils';
import { createStateContainer } from './create_state_container';
import { createStateContainerReactHelpers } from './create_state_container_react_helpers';
-import { ThemeServiceStart } from '../../../../core/public';
-import { themeServiceMock } from '../../../../core/public/mocks';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { KibanaThemeProvider } from '../../public/theme';
let container: HTMLDivElement | null;
-const theme: ThemeServiceStart = themeServiceMock.createStartContract();
beforeEach(() => {
container = document.createElement('div');
@@ -45,11 +40,9 @@ test(' passes state to ', () => {
const { Provider, Consumer } = createStateContainerReactHelpers();
ReactDOM.render(
-
-
- {(s: typeof stateContainer) => s.get().hello}
-
- ,
+
+ {(s: typeof stateContainer) => s.get().hello}
+ ,
container
);
@@ -79,11 +72,9 @@ test(' passes state to connect()()', () => {
const DemoConnected = connect(mergeProps)(Demo);
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -96,11 +87,9 @@ test('context receives stateContainer', () => {
ReactDOM.render(
/* eslint-disable @typescript-eslint/no-shadow */
-
-
- {(stateContainer) => stateContainer.get().foo}
-
- ,
+
+ {(stateContainer) => stateContainer.get().foo}
+ ,
/* eslint-enable @typescript-eslint/no-shadow */
container
);
@@ -122,11 +111,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -144,11 +131,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -169,11 +154,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -213,11 +196,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -250,11 +231,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -277,11 +256,9 @@ describe('hooks', () => {
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -310,11 +287,9 @@ describe('hooks', () => {
return <>{value}>;
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -348,11 +323,9 @@ describe('hooks', () => {
return <>{JSON.stringify(value)}>;
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
@@ -392,11 +365,9 @@ describe('hooks', () => {
return <>{JSON.stringify(value)}>;
};
ReactDOM.render(
-
-
-
-
- ,
+
+
+ ,
container
);
diff --git a/src/plugins/visualize/public/application/components/visualize_listing.tsx b/src/plugins/visualize/public/application/components/visualize_listing.tsx
index 5816626b644a8..cd3cfe6756c81 100644
--- a/src/plugins/visualize/public/application/components/visualize_listing.tsx
+++ b/src/plugins/visualize/public/application/components/visualize_listing.tsx
@@ -23,7 +23,6 @@ import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../visualizations/public
import { VisualizeServices } from '../types';
import { VisualizeConstants } from '../visualize_constants';
import { getTableColumns, getNoItemsMessage } from '../utils';
-import { getTheme } from '../../services';
export const VisualizeListing = () => {
const {
@@ -42,6 +41,7 @@ export const VisualizeListing = () => {
visualizeCapabilities,
dashboardCapabilities,
kbnUrlStateStorage,
+ theme,
},
} = useKibana();
const { pathname } = useLocation();
@@ -199,7 +199,7 @@ export const VisualizeListing = () => {
})}
toastNotifications={toastNotifications}
searchFilters={searchFilters}
- theme={getTheme()}
+ theme={theme}
>
{dashboard.dashboardFeatureFlagConfig.allowByValueEmbeddables &&
dashboardCapabilities.createNew && (
diff --git a/src/plugins/visualize/public/application/types.ts b/src/plugins/visualize/public/application/types.ts
index 3547782826f1b..d7b01dde68461 100644
--- a/src/plugins/visualize/public/application/types.ts
+++ b/src/plugins/visualize/public/application/types.ts
@@ -17,6 +17,7 @@ import type {
ToastsStart,
ScopedHistory,
AppMountParameters,
+ ThemeServiceStart,
} from 'kibana/public';
import type {
@@ -107,6 +108,7 @@ export interface VisualizeServices extends CoreStart {
usageCollection?: UsageCollectionStart;
getKibanaVersion: () => string;
spaces?: SpacesPluginStart;
+ theme: ThemeServiceStart;
}
export interface VisInstance {
diff --git a/src/plugins/visualize/public/application/utils/utils.ts b/src/plugins/visualize/public/application/utils/utils.ts
index da67c5f4e0f70..77718fd8d0cf6 100644
--- a/src/plugins/visualize/public/application/utils/utils.ts
+++ b/src/plugins/visualize/public/application/utils/utils.ts
@@ -13,7 +13,6 @@ import { Filter } from '@kbn/es-query';
import { redirectWhenMissing } from '../../../../kibana_utils/public';
import { VisualizeConstants } from '../visualize_constants';
import { VisualizeServices, VisualizeEditorVisInstance } from '../types';
-import { getTheme } from '../../services';
export const addHelpMenuToAppChrome = (chrome: ChromeStart, docLinks: DocLinksStart) => {
chrome.setHelpExtension({
@@ -92,6 +91,6 @@ export const redirectToSavedObjectPage = (
onBeforeRedirect() {
setActiveUrl(VisualizeConstants.LANDING_PAGE_PATH);
},
- theme: getTheme(),
+ theme: services.theme,
})(error);
};
diff --git a/src/plugins/visualize/public/plugin.ts b/src/plugins/visualize/public/plugin.ts
index 6ce010654d7d0..7ff3434286b6b 100644
--- a/src/plugins/visualize/public/plugin.ts
+++ b/src/plugins/visualize/public/plugin.ts
@@ -49,7 +49,6 @@ import type { SpacesApi } from '../../../../x-pack/plugins/spaces/public';
import { setVisEditorsRegistry, setUISettings, setUsageCollector } from './services';
import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry';
import { VisualizeLocatorDefinition } from '../common/locator';
-import { setTheme } from './services';
export interface VisualizePluginStartDependencies {
data: DataPublicPluginStart;
@@ -137,7 +136,6 @@ export class VisualizePlugin
stopUrlTracker();
};
- setTheme(core.theme);
setUISettings(core.uiSettings);
core.application.register({
diff --git a/src/plugins/visualize/public/services.ts b/src/plugins/visualize/public/services.ts
index 285abc7c243a9..3f91762c60780 100644
--- a/src/plugins/visualize/public/services.ts
+++ b/src/plugins/visualize/public/services.ts
@@ -7,7 +7,7 @@
*/
import { createGetterSetter } from '../../../plugins/kibana_utils/public';
-import type { IUiSettingsClient, ThemeServiceStart } from '../../../core/public';
+import type { IUiSettingsClient } from '../../../core/public';
import type { VisEditorsRegistry } from './vis_editors_registry';
import type { UsageCollectionStart } from '../../usage_collection/public';
@@ -20,5 +20,3 @@ export const [getUsageCollector, setUsageCollector] = createGetterSetter('VisEditorsRegistry');
-
-export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/x-pack/plugins/reporting/kibana.json b/x-pack/plugins/reporting/kibana.json
index 554679d776575..123c23e5e1c29 100644
--- a/x-pack/plugins/reporting/kibana.json
+++ b/x-pack/plugins/reporting/kibana.json
@@ -25,5 +25,5 @@
],
"server": true,
"ui": true,
- "requiredBundles": ["kibanaReact", "kibanaUtils", "discover"]
+ "requiredBundles": ["kibanaReact", "discover"]
}
diff --git a/x-pack/plugins/reporting/public/index.ts b/x-pack/plugins/reporting/public/index.ts
index e330bef849be4..fdd5769ab3e00 100644
--- a/x-pack/plugins/reporting/public/index.ts
+++ b/x-pack/plugins/reporting/public/index.ts
@@ -5,8 +5,7 @@
* 2.0.
*/
-import { PluginInitializerContext, ThemeServiceStart } from 'src/core/public';
-import { createGetterSetter } from '../../../../src/plugins/kibana_utils/public';
+import { PluginInitializerContext } from 'src/core/public';
import { ReportingAPIClient } from './lib/reporting_api_client';
import { ReportingPublicPlugin } from './plugin';
import { getSharedComponents } from './shared';
@@ -28,5 +27,3 @@ export { ReportingAPIClient, ReportingPublicPlugin as Plugin };
export function plugin(initializerContext: PluginInitializerContext): ReportingPublicPlugin {
return new ReportingPublicPlugin(initializerContext);
}
-
-export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts
index 1bb8c3229407d..78742af7fe879 100644
--- a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts
+++ b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts
@@ -7,7 +7,7 @@
import sinon, { stub } from 'sinon';
import { NotificationsStart } from 'src/core/public';
-import { coreMock } from '../../../../../src/core/public/mocks';
+import { coreMock, themeServiceMock } from '../../../../../src/core/public/mocks';
import { JobSummary, ReportApiJSON } from '../../common/types';
import { Job } from './job';
import { ReportingAPIClient } from './reporting_api_client';
@@ -46,19 +46,21 @@ const notificationsMock = {
},
} as unknown as NotificationsStart;
+const theme = themeServiceMock.createStartContract();
+
describe('stream handler', () => {
afterEach(() => {
sinon.reset();
});
it('constructs', () => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
expect(sh).not.toBe(null);
});
describe('findChangedStatusJobs', () => {
it('finds no changed status jobs from empty', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
const findJobs = sh.findChangedStatusJobs([]);
findJobs.subscribe((data) => {
expect(data).toEqual({ completed: [], failed: [] });
@@ -67,7 +69,7 @@ describe('stream handler', () => {
});
it('finds changed status jobs', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
const findJobs = sh.findChangedStatusJobs([
'job-source-mock1',
'job-source-mock2',
@@ -83,7 +85,7 @@ describe('stream handler', () => {
describe('showNotifications', () => {
it('show success', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
sh.showNotifications({
completed: [
{
@@ -104,7 +106,7 @@ describe('stream handler', () => {
});
it('show max length warning', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
sh.showNotifications({
completed: [
{
@@ -126,7 +128,7 @@ describe('stream handler', () => {
});
it('show csv formulas warning', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
sh.showNotifications({
completed: [
{
@@ -148,7 +150,7 @@ describe('stream handler', () => {
});
it('show failed job toast', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
sh.showNotifications({
completed: [],
failed: [
@@ -169,7 +171,7 @@ describe('stream handler', () => {
});
it('show multiple toast', (done) => {
- const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock);
+ const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme);
sh.showNotifications({
completed: [
{
diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.ts b/x-pack/plugins/reporting/public/lib/stream_handler.ts
index 304b4fb73374d..27e220221156e 100644
--- a/x-pack/plugins/reporting/public/lib/stream_handler.ts
+++ b/x-pack/plugins/reporting/public/lib/stream_handler.ts
@@ -8,7 +8,7 @@
import { i18n } from '@kbn/i18n';
import * as Rx from 'rxjs';
import { catchError, map } from 'rxjs/operators';
-import { NotificationsSetup } from 'src/core/public';
+import { NotificationsSetup, ThemeServiceStart } from 'src/core/public';
import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JOB_STATUSES } from '../../common/constants';
import { JobId, JobSummary, JobSummarySet } from '../../common/types';
import {
@@ -37,7 +37,11 @@ function getReportStatus(src: Job): JobSummary {
}
export class ReportingNotifierStreamHandler {
- constructor(private notifications: NotificationsSetup, private apiClient: ReportingAPIClient) {}
+ constructor(
+ private notifications: NotificationsSetup,
+ private apiClient: ReportingAPIClient,
+ private theme: ThemeServiceStart
+ ) {}
/*
* Use Kibana Toast API to show our messages
@@ -54,7 +58,8 @@ export class ReportingNotifierStreamHandler {
getWarningFormulasToast(
job,
this.apiClient.getManagementLink,
- this.apiClient.getDownloadLink
+ this.apiClient.getDownloadLink,
+ this.theme
)
);
} else if (job.maxSizeReached) {
@@ -62,12 +67,18 @@ export class ReportingNotifierStreamHandler {
getWarningMaxSizeToast(
job,
this.apiClient.getManagementLink,
- this.apiClient.getDownloadLink
+ this.apiClient.getDownloadLink,
+ this.theme
)
);
} else {
this.notifications.toasts.addSuccess(
- getSuccessToast(job, this.apiClient.getManagementLink, this.apiClient.getDownloadLink)
+ getSuccessToast(
+ job,
+ this.apiClient.getManagementLink,
+ this.apiClient.getDownloadLink,
+ this.theme
+ )
);
}
}
@@ -76,7 +87,7 @@ export class ReportingNotifierStreamHandler {
for (const job of failedJobs) {
const errorText = await this.apiClient.getError(job.id);
this.notifications.toasts.addDanger(
- getFailureToast(errorText, job, this.apiClient.getManagementLink)
+ getFailureToast(errorText, job, this.apiClient.getManagementLink, this.theme)
);
}
return { completed: completedJobs, failed: failedJobs };
@@ -120,7 +131,8 @@ export class ReportingNotifierStreamHandler {
i18n.translate('xpack.reporting.publicNotifier.httpErrorMessage', {
defaultMessage: 'Could not check Reporting job status!',
}),
- err
+ err,
+ this.theme
)
); // prettier-ignore
window.console.error(err);
diff --git a/x-pack/plugins/reporting/public/notifier/general_error.tsx b/x-pack/plugins/reporting/public/notifier/general_error.tsx
index b81940efc96c3..66fff4d00ceeb 100644
--- a/x-pack/plugins/reporting/public/notifier/general_error.tsx
+++ b/x-pack/plugins/reporting/public/notifier/general_error.tsx
@@ -8,11 +8,14 @@
import React, { Fragment } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
-import { ToastInput } from 'src/core/public';
+import { ThemeServiceStart, ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
-import { getTheme } from '..';
-export const getGeneralErrorToast = (errorText: string, err: Error): ToastInput => ({
+export const getGeneralErrorToast = (
+ errorText: string,
+ err: Error,
+ theme: ThemeServiceStart
+): ToastInput => ({
text: toMountPoint(
@@ -26,7 +29,7 @@ export const getGeneralErrorToast = (errorText: string, err: Error): ToastInput
defaultMessage="Try refreshing the page."
/>
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
iconType: undefined,
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_failure.tsx b/x-pack/plugins/reporting/public/notifier/job_failure.tsx
index 2f305e19f7e62..87fbc72d29ab8 100644
--- a/x-pack/plugins/reporting/public/notifier/job_failure.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_failure.tsx
@@ -9,15 +9,15 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
-import { ToastInput } from 'src/core/public';
-import { getTheme } from '..';
+import { ThemeServiceStart, ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobSummary, ManagementLinkFn } from '../../common/types';
export const getFailureToast = (
errorText: string,
job: JobSummary,
- getManagmenetLink: ManagementLinkFn
+ getManagmenetLink: ManagementLinkFn,
+ theme: ThemeServiceStart
): ToastInput => {
return {
title: toMountPoint(
@@ -26,7 +26,7 @@ export const getFailureToast = (
defaultMessage="Could not create report for {reportObjectType} '{reportObjectTitle}'."
values={{ reportObjectType: job.jobtype, reportObjectTitle: job.title }}
/>,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
text: toMountPoint(
@@ -61,7 +61,7 @@ export const getFailureToast = (
/>
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
iconType: undefined,
'data-test-subj': 'completeReportFailure',
diff --git a/x-pack/plugins/reporting/public/notifier/job_success.tsx b/x-pack/plugins/reporting/public/notifier/job_success.tsx
index 92f9d2f206616..f949c27f6fedb 100644
--- a/x-pack/plugins/reporting/public/notifier/job_success.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_success.tsx
@@ -7,8 +7,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
-import { ToastInput } from 'src/core/public';
-import { getTheme } from '..';
+import { ThemeServiceStart, ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -17,7 +16,8 @@ import { ReportLink } from './report_link';
export const getSuccessToast = (
job: JobSummary,
getReportLink: () => string,
- getDownloadLink: (jobId: JobId) => string
+ getDownloadLink: (jobId: JobId) => string,
+ theme: ThemeServiceStart
): ToastInput => ({
title: toMountPoint(
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
color: 'success',
text: toMountPoint(
@@ -35,7 +35,7 @@ export const getSuccessToast = (
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
'data-test-subj': 'completeReportSuccess',
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx b/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
index 8dde77afa8011..08c87a40a829a 100644
--- a/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_warning_formulas.tsx
@@ -7,8 +7,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
-import { ToastInput } from 'src/core/public';
-import { getTheme } from '..';
+import { ThemeServiceStart, ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -17,7 +16,8 @@ import { ReportLink } from './report_link';
export const getWarningFormulasToast = (
job: JobSummary,
getReportLink: () => string,
- getDownloadLink: (jobId: JobId) => string
+ getDownloadLink: (jobId: JobId) => string,
+ theme: ThemeServiceStart
): ToastInput => ({
title: toMountPoint(
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
text: toMountPoint(
@@ -40,7 +40,7 @@ export const getWarningFormulasToast = (
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
'data-test-subj': 'completeReportCsvFormulasWarning',
});
diff --git a/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx b/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
index 24ab6b0945bed..629ac44adeae8 100644
--- a/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
+++ b/x-pack/plugins/reporting/public/notifier/job_warning_max_size.tsx
@@ -7,8 +7,7 @@
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Fragment } from 'react';
-import { ToastInput } from 'src/core/public';
-import { getTheme } from '..';
+import { ThemeServiceStart, ToastInput } from 'src/core/public';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
import { JobId, JobSummary } from '../../common/types';
import { DownloadButton } from './job_download_button';
@@ -17,7 +16,8 @@ import { ReportLink } from './report_link';
export const getWarningMaxSizeToast = (
job: JobSummary,
getReportLink: () => string,
- getDownloadLink: (jobId: JobId) => string
+ getDownloadLink: (jobId: JobId) => string,
+ theme: ThemeServiceStart
): ToastInput => ({
title: toMountPoint(
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
text: toMountPoint(
@@ -40,7 +40,7 @@ export const getWarningMaxSizeToast = (
,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
'data-test-subj': 'completeReportMaxSizeWarning',
});
diff --git a/x-pack/plugins/reporting/public/plugin.ts b/x-pack/plugins/reporting/public/plugin.ts
index e6db6be1ab16f..77c8489bb8992 100644
--- a/x-pack/plugins/reporting/public/plugin.ts
+++ b/x-pack/plugins/reporting/public/plugin.ts
@@ -17,6 +17,7 @@ import {
NotificationsSetup,
Plugin,
PluginInitializerContext,
+ ThemeServiceStart,
} from 'src/core/public';
import type { ScreenshottingSetup } from '../../screenshotting/public';
import { CONTEXT_MENU_TRIGGER } from '../../../../src/plugins/embeddable/public';
@@ -29,7 +30,7 @@ import { ManagementSetup, ManagementStart } from '../../../../src/plugins/manage
import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/public';
import { durationToNumber } from '../common/schema_utils';
import { JobId, JobSummarySet } from '../common/types';
-import { ReportingSetup, ReportingStart, setTheme } from './';
+import { ReportingSetup, ReportingStart } from './';
import { ReportingAPIClient } from './lib/reporting_api_client';
import { ReportingNotifierStreamHandler as StreamHandler } from './lib/stream_handler';
import { getGeneralErrorToast } from './notifier';
@@ -56,13 +57,18 @@ function getStored(): JobId[] {
return sessionValue ? JSON.parse(sessionValue) : [];
}
-function handleError(notifications: NotificationsSetup, err: Error): Rx.Observable {
+function handleError(
+ notifications: NotificationsSetup,
+ err: Error,
+ theme: ThemeServiceStart
+): Rx.Observable {
notifications.toasts.addDanger(
getGeneralErrorToast(
i18n.translate('xpack.reporting.publicNotifier.pollingErrorMessage', {
defaultMessage: 'Reporting notifier error!',
}),
- err
+ err,
+ theme
)
);
window.console.error(err);
@@ -158,7 +164,6 @@ export class ReportingPublicPlugin
const startServices$ = Rx.from(getStartServices());
const usesUiCapabilities = !this.config.roles.enabled;
- setTheme(core.theme);
const apiClient = this.getApiClient(core.http, core.uiSettings);
@@ -236,6 +241,7 @@ export class ReportingPublicPlugin
startServices$,
uiSettings,
usesUiCapabilities,
+ theme: core.theme,
})
);
@@ -247,6 +253,7 @@ export class ReportingPublicPlugin
startServices$,
uiSettings,
usesUiCapabilities,
+ theme: core.theme,
})
);
@@ -256,7 +263,7 @@ export class ReportingPublicPlugin
public start(core: CoreStart) {
const { notifications } = core;
const apiClient = this.getApiClient(core.http, core.uiSettings);
- const streamHandler = new StreamHandler(notifications, apiClient);
+ const streamHandler = new StreamHandler(notifications, apiClient, core.theme);
const interval = durationToNumber(this.config.poll.jobsRefresh.interval);
Rx.timer(0, interval)
.pipe(
@@ -265,7 +272,7 @@ export class ReportingPublicPlugin
filter((storedJobs) => storedJobs.length > 0), // stop the pipeline here if there are none pending
mergeMap((storedJobs) => streamHandler.findChangedStatusJobs(storedJobs)), // look up the latest status of all pending jobs on the server
mergeMap(({ completed, failed }) => streamHandler.showNotifications({ completed, failed })),
- catchError((err) => handleError(notifications, err))
+ catchError((err) => handleError(notifications, err, core.theme))
)
.subscribe();
diff --git a/x-pack/plugins/reporting/public/share_context_menu/index.ts b/x-pack/plugins/reporting/public/share_context_menu/index.ts
index 321a5a29281af..6a5dbf970e0b4 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/index.ts
+++ b/x-pack/plugins/reporting/public/share_context_menu/index.ts
@@ -6,7 +6,7 @@
*/
import * as Rx from 'rxjs';
-import type { IUiSettingsClient, ToastsSetup } from 'src/core/public';
+import type { IUiSettingsClient, ThemeServiceSetup, ToastsSetup } from 'src/core/public';
import { CoreStart } from 'src/core/public';
import type { LayoutParams } from '../../../screenshotting/common';
import type { LicensingPluginSetup } from '../../../licensing/public';
@@ -19,6 +19,7 @@ export interface ExportPanelShareOpts {
license$: LicensingPluginSetup['license$']; // FIXME: 'license$' is deprecated
startServices$: Rx.Observable<[CoreStart, object, unknown]>;
usesUiCapabilities: boolean;
+ theme: ThemeServiceSetup;
}
export interface ReportingSharingData {
diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx
index 8859d01e4fe9a..b264c96361122 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx
@@ -21,6 +21,7 @@ export const ReportingCsvShareProvider = ({
license$,
startServices$,
usesUiCapabilities,
+ theme,
}: ExportPanelShareOpts) => {
let licenseToolTipContent = '';
let licenseHasCsvReporting = false;
@@ -96,6 +97,7 @@ export const ReportingCsvShareProvider = ({
objectId={objectId}
getJobParams={getJobParams}
onClose={onClose}
+ theme={theme}
/>
),
},
diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx
index 610781f3b6ea0..3cc8cbacc7921 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx
@@ -63,6 +63,7 @@ export const reportingScreenshotShareProvider = ({
license$,
startServices$,
usesUiCapabilities,
+ theme,
}: ExportPanelShareOpts) => {
let licenseToolTipContent = '';
let licenseDisabled = true;
@@ -156,6 +157,7 @@ export const reportingScreenshotShareProvider = ({
getJobParams={getJobParams(apiClient, jobProviderOptions, pngReportType)}
isDirty={isDirty}
onClose={onClose}
+ theme={theme}
/>
),
},
@@ -191,6 +193,7 @@ export const reportingScreenshotShareProvider = ({
getJobParams={getJobParams(apiClient, jobProviderOptions, pdfReportType)}
isDirty={isDirty}
onClose={onClose}
+ theme={theme}
/>
),
},
diff --git a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.test.tsx b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.test.tsx
index e9dd584e51f82..ef3e9940238c1 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.test.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.test.tsx
@@ -10,6 +10,7 @@ import { mountWithIntl } from '@kbn/test/jest';
import {
httpServiceMock,
notificationServiceMock,
+ themeServiceMock,
uiSettingsServiceMock,
} from 'src/core/public/mocks';
import { ReportingAPIClient } from '../../lib/reporting_api_client';
@@ -21,6 +22,8 @@ jest.mock('./constants', () => ({
}));
import * as constants from './constants';
+const theme = themeServiceMock.createSetupContract();
+
describe('ReportingPanelContent', () => {
const props: Partial = {
layoutId: 'super_cool_layout_id_X',
@@ -58,6 +61,7 @@ describe('ReportingPanelContent', () => {
apiClient={apiClient}
toasts={toasts}
uiSettings={uiSettings}
+ theme={theme}
{...props}
{...newProps}
/>
diff --git a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
index dc7ea454689e5..e1fa1198cf1f8 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/reporting_panel_content/reporting_panel_content.tsx
@@ -18,9 +18,8 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n-react';
import React, { Component, ReactElement } from 'react';
-import { IUiSettingsClient, ToastsSetup } from 'src/core/public';
+import { IUiSettingsClient, ThemeServiceSetup, ToastsSetup } from 'src/core/public';
import url from 'url';
-import { getTheme } from '../..';
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
import {
CSV_REPORT_TYPE,
@@ -47,6 +46,7 @@ export interface ReportingPanelProps {
options?: ReactElement | null;
isDirty?: boolean;
onClose?: () => void;
+ theme: ThemeServiceSetup;
}
export type Props = ReportingPanelProps & { intl: InjectedIntl };
@@ -293,7 +293,7 @@ class ReportingPanelContentUi extends Component {
),
}}
/>,
- { theme$: getTheme().theme$ }
+ { theme$: this.props.theme.theme$ }
),
'data-test-subj': 'queueReportSuccess',
});
diff --git a/x-pack/plugins/reporting/public/share_context_menu/screen_capture_panel_content.test.tsx b/x-pack/plugins/reporting/public/share_context_menu/screen_capture_panel_content.test.tsx
index 7a2fa52d010e3..ebf741c79bd86 100644
--- a/x-pack/plugins/reporting/public/share_context_menu/screen_capture_panel_content.test.tsx
+++ b/x-pack/plugins/reporting/public/share_context_menu/screen_capture_panel_content.test.tsx
@@ -8,7 +8,7 @@
import { mount } from 'enzyme';
import React from 'react';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
-import { coreMock } from 'src/core/public/mocks';
+import { coreMock, themeServiceMock } from 'src/core/public/mocks';
import { ReportingAPIClient } from '../lib/reporting_api_client';
import { ScreenCapturePanelContent } from './screen_capture_panel_content';
@@ -27,6 +27,8 @@ const getJobParamsDefault = () => ({
browserTimezone: 'America/New_York',
});
+const theme = themeServiceMock.createSetupContract();
+
test('ScreenCapturePanelContent renders the default view properly', () => {
const component = mount(
@@ -37,6 +39,7 @@ test('ScreenCapturePanelContent renders the default view properly', () => {
uiSettings={uiSettings}
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
+ theme={theme}
/>
);
@@ -56,6 +59,7 @@ test('ScreenCapturePanelContent properly renders a view with "canvas" layout opt
uiSettings={uiSettings}
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
+ theme={theme}
/>
);
@@ -75,6 +79,7 @@ test('ScreenCapturePanelContent allows POST URL to be copied when objectId is pr
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
objectId={'1234-5'}
+ theme={theme}
/>
);
@@ -93,6 +98,7 @@ test('ScreenCapturePanelContent does not allow POST URL to be copied when object
uiSettings={uiSettings}
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
+ theme={theme}
/>
);
@@ -111,6 +117,7 @@ test('ScreenCapturePanelContent properly renders a view with "print" layout opti
uiSettings={uiSettings}
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
+ theme={theme}
/>
);
@@ -130,6 +137,7 @@ test('ScreenCapturePanelContent decorated job params are visible in the POST URL
uiSettings={uiSettings}
toasts={coreSetup.notifications.toasts}
getJobParams={getJobParamsDefault}
+ theme={theme}
/>
);
diff --git a/x-pack/plugins/reporting/public/shared/get_shared_components.tsx b/x-pack/plugins/reporting/public/shared/get_shared_components.tsx
index b08036e8b1c80..0906bf85c9538 100644
--- a/x-pack/plugins/reporting/public/shared/get_shared_components.tsx
+++ b/x-pack/plugins/reporting/public/shared/get_shared_components.tsx
@@ -35,6 +35,7 @@ export function getSharedComponents(core: CoreSetup, apiClient: ReportingAPIClie
apiClient={apiClient}
toasts={core.notifications.toasts}
uiSettings={core.uiSettings}
+ theme={core.theme}
{...props}
/>
);
@@ -48,6 +49,7 @@ export function getSharedComponents(core: CoreSetup, apiClient: ReportingAPIClie
apiClient={apiClient}
toasts={core.notifications.toasts}
uiSettings={core.uiSettings}
+ theme={core.theme}
{...props}
/>
);
@@ -61,6 +63,7 @@ export function getSharedComponents(core: CoreSetup, apiClient: ReportingAPIClie
apiClient={apiClient}
toasts={core.notifications.toasts}
uiSettings={core.uiSettings}
+ theme={core.theme}
{...props}
/>
);
diff --git a/x-pack/plugins/runtime_fields/public/plugin.test.ts b/x-pack/plugins/runtime_fields/public/plugin.test.ts
index 0f72d99ec5d4f..fc36eecc12f0a 100644
--- a/x-pack/plugins/runtime_fields/public/plugin.test.ts
+++ b/x-pack/plugins/runtime_fields/public/plugin.test.ts
@@ -6,7 +6,7 @@
*/
import { CoreSetup } from 'src/core/public';
-import { coreMock } from 'src/core/public/mocks';
+import { coreMock, themeServiceMock } from 'src/core/public/mocks';
jest.mock('../../../../src/plugins/kibana_react/public', () => {
const original = jest.requireActual('../../../../src/plugins/kibana_react/public');
@@ -52,6 +52,7 @@ describe('RuntimeFieldsPlugin', () => {
openFlyout,
},
uiSettings: {},
+ theme: themeServiceMock.createStartContract(),
};
coreSetup.getStartServices = async () => [mockCore] as any;
const setupApi = await plugin.setup(coreSetup, {});
From 3419d8ed336868e8d07d1f77cf0d34b6b3e3fc69 Mon Sep 17 00:00:00 2001
From: shivindera
Date: Thu, 6 Jan 2022 19:57:46 +0100
Subject: [PATCH 5/7] fix for topnav erroring out due to missing theme
---
src/plugins/data/public/plugin.ts | 2 ++
src/plugins/data/public/services.ts | 4 +++-
.../data/public/ui/query_string_input/query_bar_top_row.tsx | 3 ---
.../public/ui/query_string_input/query_string_input.tsx | 6 +++---
src/plugins/data/public/ui/search_bar/create_search_bar.tsx | 1 -
src/plugins/data/public/ui/search_bar/search_bar.tsx | 3 ---
6 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts
index 9e0fae0053378..7d19c1eb3ac19 100644
--- a/src/plugins/data/public/plugin.ts
+++ b/src/plugins/data/public/plugin.ts
@@ -27,6 +27,7 @@ import {
setOverlays,
setSearchService,
setUiSettings,
+ setTheme,
} from './services';
import { createSearchBar } from './ui/search_bar/create_search_bar';
import {
@@ -82,6 +83,7 @@ export class DataPublicPlugin
const startServices = createStartServicesGetter(core.getStartServices);
this.usageCollection = usageCollection;
+ setTheme(core.theme);
const searchService = this.searchService.setup(core, {
bfetch,
diff --git a/src/plugins/data/public/services.ts b/src/plugins/data/public/services.ts
index c1a0ae1ac1b53..5c52a1e695359 100644
--- a/src/plugins/data/public/services.ts
+++ b/src/plugins/data/public/services.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { NotificationsStart, CoreStart } from 'src/core/public';
+import { NotificationsStart, CoreStart, ThemeServiceStart } from 'src/core/public';
import { createGetterSetter } from '../../kibana_utils/public';
import { IndexPatternsContract } from './data_views';
import { DataPublicPluginStart } from './types';
@@ -24,3 +24,5 @@ export const [getIndexPatterns, setIndexPatterns] =
export const [getSearchService, setSearchService] =
createGetterSetter('Search');
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
index 1353a0843e64a..e5da2bb9f089d 100644
--- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx
@@ -24,7 +24,6 @@ import {
EuiSuperUpdateButton,
OnRefreshProps,
} from '@elastic/eui';
-import { ThemeServiceStart } from 'kibana/public';
import { IDataPluginServices, IIndexPattern, TimeRange, TimeHistoryContract, Query } from '../..';
import { useKibana, withKibana } from '../../../../kibana_react/public';
import QueryStringInputUI from './query_string_input';
@@ -74,7 +73,6 @@ export interface QueryBarTopRowProps {
showAutoRefreshOnly?: boolean;
timeHistory?: TimeHistoryContract;
timeRangeForSuggestionsOverride?: boolean;
- theme: ThemeServiceStart;
}
const SharingMetaFields = React.memo(function SharingMetaFields({
@@ -361,7 +359,6 @@ export const QueryBarTopRow = React.memo(
nonKqlMode={props.nonKqlMode}
nonKqlModeHelpText={props.nonKqlModeHelpText}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
- theme={props.theme}
/>
);
diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
index 36953c1745b75..6464f02dd7cb7 100644
--- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
@@ -26,7 +26,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { compact, debounce, isEqual, isFunction } from 'lodash';
-import { ThemeServiceStart, Toast } from 'src/core/public';
+import { Toast } from 'src/core/public';
import { METRIC_TYPE } from '@kbn/analytics';
import { IDataPluginServices, IIndexPattern, Query } from '../..';
@@ -40,6 +40,7 @@ import type { SuggestionsListSize } from '../typeahead/suggestions_component';
import { SuggestionsComponent } from '..';
import { getFieldSubtypeNested, KIBANA_USER_QUERY_LANGUAGE_KEY } from '../../../common';
import { onRaf } from '../utils';
+import { getTheme } from '../../services';
export interface QueryStringInputProps {
indexPatterns: Array;
@@ -83,7 +84,6 @@ export interface QueryStringInputProps {
* Override whether autocomplete suggestions are restricted by time range.
*/
timeRangeForSuggestionsOverride?: boolean;
- theme: ThemeServiceStart;
}
interface Props extends QueryStringInputProps {
@@ -489,7 +489,7 @@ export default class QueryStringInputUI extends PureComponent {
,
- { theme$: this.props.theme.theme$ }
+ { theme$: getTheme().theme$ }
),
});
}
diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
index 3da2e7f4093cd..fda6a74e4b500 100644
--- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
+++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx
@@ -197,7 +197,6 @@ export function createSearchBar({ core, storage, data, usageCollection }: Statef
isClearable={props.isClearable}
placeholder={props.placeholder}
{...overrideDefaultBehaviors(props)}
- theme={core.theme}
/>
);
diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx
index a6bccb6770eba..e33977f8d9048 100644
--- a/src/plugins/data/public/ui/search_bar/search_bar.tsx
+++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx
@@ -16,7 +16,6 @@ import memoizeOne from 'memoize-one';
import { METRIC_TYPE } from '@kbn/analytics';
import { Query, Filter } from '@kbn/es-query';
-import { ThemeServiceStart } from 'kibana/public';
import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public';
import QueryBarTopRow from '../query_string_input/query_bar_top_row';
@@ -81,7 +80,6 @@ export interface SearchBarOwnProps {
displayStyle?: 'inPage' | 'detached';
// super update button background fill control
fillSubmitButton?: boolean;
- theme: ThemeServiceStart;
}
export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps;
@@ -394,7 +392,6 @@ class SearchBarUI extends Component {
nonKqlMode={this.props.nonKqlMode}
nonKqlModeHelpText={this.props.nonKqlModeHelpText}
timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride}
- theme={this.props.theme}
/>
);
}
From b0a13ac52c626ab66fb05f294c7bed4b7f30d01d Mon Sep 17 00:00:00 2001
From: shivindera
Date: Thu, 6 Jan 2022 22:04:25 +0100
Subject: [PATCH 6/7] some optimizations and remove dependency on
getter/setters
---
.../components/table/table.test.tsx | 5 ++++-
.../components/table/table.tsx | 16 +++++++++++-----
.../indexed_fields_table.tsx | 4 +++-
.../components/edit_index_pattern/tabs/tabs.tsx | 4 +++-
src/plugins/data_view_management/public/index.ts | 5 +----
.../management_app/mount_management_section.tsx | 4 ++--
.../data_view_management/public/plugin.ts | 2 --
src/plugins/embeddable/public/index.ts | 4 ----
.../public/lib/embeddables/error_embeddable.tsx | 3 +--
.../public/lib/panel/embeddable_panel.tsx | 14 ++++++++------
.../add_panel/add_panel_action.test.tsx | 9 ++++++---
.../panel_actions/add_panel/add_panel_action.ts | 4 +++-
.../add_panel/open_add_panel_flyout.tsx | 7 ++++---
src/plugins/embeddable/public/plugin.tsx | 6 +++---
src/plugins/embeddable/public/services.ts | 12 ++++++++++++
.../share/public/services/share_menu_manager.tsx | 11 +++++------
.../url_service/redirect/components/page.tsx | 11 +++++------
.../url_service/redirect/redirect_manager.ts | 3 +--
.../share/public/url_service/redirect/render.ts | 2 +-
.../public/context_menu/open_context_menu.tsx | 2 +-
src/plugins/ui_actions/public/index.ts | 4 ----
src/plugins/ui_actions/public/plugin.ts | 2 +-
src/plugins/ui_actions/public/services.ts | 12 ++++++++++++
.../reporting_example/public/application.tsx | 3 +--
24 files changed, 88 insertions(+), 61 deletions(-)
create mode 100644 src/plugins/embeddable/public/services.ts
create mode 100644 src/plugins/ui_actions/public/services.ts
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.test.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.test.tsx
index dd78b00f9775e..f85f7bb254826 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.test.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.test.tsx
@@ -11,7 +11,9 @@ import { shallow } from 'enzyme';
import { IndexPattern } from 'src/plugins/data/public';
import { IndexedFieldItem } from '../../types';
import { Table, renderFieldName, getConflictModalContent } from './table';
-import { overlayServiceMock } from 'src/core/public/mocks';
+import { overlayServiceMock, themeServiceMock } from 'src/core/public/mocks';
+
+const theme = themeServiceMock.createStartContract();
const indexPattern = {
timeFieldName: 'timestamp',
@@ -89,6 +91,7 @@ const renderTable = (
editField={editField}
deleteField={() => {}}
openModal={overlayServiceMock.createStartContract().openModal}
+ theme={theme}
/>
);
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
index fa696625da52c..7e915e3c930a5 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/components/table/table.tsx
@@ -7,7 +7,7 @@
*/
import React, { PureComponent } from 'react';
-import { OverlayModalStart } from 'src/core/public';
+import { OverlayModalStart, ThemeServiceStart } from 'src/core/public';
import {
EuiIcon,
@@ -32,7 +32,6 @@ import { toMountPoint } from '../../../../../../../kibana_react/public';
import { IIndexPattern } from '../../../../../../../data/public';
import { IndexedFieldItem } from '../../types';
-import { getTheme } from '../../../../../';
// localized labels
const additionalInfoAriaLabel = i18n.translate(
@@ -180,6 +179,7 @@ interface IndexedFieldProps {
editField: (field: IndexedFieldItem) => void;
deleteField: (fieldName: string) => void;
openModal: OverlayModalStart['open'];
+ theme: ThemeServiceStart;
}
const getItems = (conflictDescriptions: IndexedFieldItem['conflictDescriptions']) => {
@@ -312,7 +312,8 @@ export const getConflictModalContent = ({
const getConflictBtn = (
fieldName: string,
conflictDescriptions: IndexedFieldItem['conflictDescriptions'],
- openModal: IndexedFieldProps['openModal']
+ openModal: IndexedFieldProps['openModal'],
+ theme: ThemeServiceStart
) => {
const onClick = () => {
const overlayRef = openModal(
@@ -324,7 +325,7 @@ const getConflictBtn = (
fieldName,
conflictDescriptions,
}),
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
)
);
};
@@ -357,7 +358,12 @@ export class Table extends PureComponent {
{type === 'conflict' && conflictDescription ? '' : type}
{field.conflictDescriptions
- ? getConflictBtn(field.name, field.conflictDescriptions, this.props.openModal)
+ ? getConflictBtn(
+ field.name,
+ field.conflictDescriptions,
+ this.props.openModal,
+ this.props.theme
+ )
: ''}
);
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx
index a72c87655fd63..29b8d82a99704 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx
@@ -8,7 +8,7 @@
import React, { Component } from 'react';
import { createSelector } from 'reselect';
-import { OverlayStart } from 'src/core/public';
+import { OverlayStart, ThemeServiceStart } from 'src/core/public';
import { IndexPatternField, IndexPattern } from '../../../../../../plugins/data/public';
import { useKibana } from '../../../../../../plugins/kibana_react/public';
import { Table } from './components/table';
@@ -28,6 +28,7 @@ interface IndexedFieldsTableProps {
fieldWildcardMatcher: (filters: any[]) => (val: any) => boolean;
userEditPermission: boolean;
openModal: OverlayStart['openModal'];
+ theme: ThemeServiceStart;
}
interface IndexedFieldsTableState {
@@ -129,6 +130,7 @@ class IndexedFields extends Component this.props.helpers.editField(field.name)}
deleteField={(fieldName) => this.props.helpers.deleteField(fieldName)}
openModal={this.props.openModal}
+ theme={this.props.theme}
/>
);
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index b5940fa8d1bb0..58b064fa79893 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -80,7 +80,7 @@ export function Tabs({
location,
refreshFields,
}: TabsProps) {
- const { application, uiSettings, docLinks, dataViewFieldEditor, overlays } =
+ const { application, uiSettings, docLinks, dataViewFieldEditor, overlays, theme } =
useKibana().services;
const [fieldFilter, setFieldFilter] = useState('');
const [indexedFieldTypeFilter, setIndexedFieldTypeFilter] = useState('');
@@ -236,6 +236,7 @@ export function Tabs({
getFieldInfo,
}}
openModal={overlays.openModal}
+ theme={theme}
/>
)}
@@ -295,6 +296,7 @@ export function Tabs({
DeleteRuntimeFieldProvider,
refreshFields,
overlays,
+ theme,
]
);
diff --git a/src/plugins/data_view_management/public/index.ts b/src/plugins/data_view_management/public/index.ts
index 01f6445efb56c..65b71ee6053e3 100644
--- a/src/plugins/data_view_management/public/index.ts
+++ b/src/plugins/data_view_management/public/index.ts
@@ -17,13 +17,10 @@
* in the setup/start interfaces in `plugin.ts`. The remaining items exported here are
* either types, or static code.
*/
-import { PluginInitializerContext, ThemeServiceStart } from 'src/core/public';
-import { createGetterSetter } from '../../kibana_utils/public';
+import { PluginInitializerContext } from 'src/core/public';
import { IndexPatternManagementPlugin } from './plugin';
export type { IndexPatternManagementSetup, IndexPatternManagementStart } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new IndexPatternManagementPlugin(initializerContext);
}
-
-export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
index eeee5e92b8dee..4bc0a204f68a1 100644
--- a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
+++ b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx
@@ -39,7 +39,7 @@ export async function mountManagementSection(
params: ManagementAppMountParams
) {
const [
- { chrome, application, uiSettings, notifications, overlays, http, docLinks },
+ { chrome, application, uiSettings, notifications, overlays, http, docLinks, theme },
{ data, dataViewFieldEditor, dataViewEditor },
indexPatternManagementStart,
] = await getStartServices();
@@ -67,7 +67,7 @@ export async function mountManagementSection(
ReactDOM.render(
-
+
diff --git a/src/plugins/data_view_management/public/plugin.ts b/src/plugins/data_view_management/public/plugin.ts
index 7d249c5d6a3b8..742a623dcb084 100644
--- a/src/plugins/data_view_management/public/plugin.ts
+++ b/src/plugins/data_view_management/public/plugin.ts
@@ -14,7 +14,6 @@ import { UrlForwardingSetup } from '../../url_forwarding/public';
import { ManagementSetup } from '../../management/public';
import { IndexPatternFieldEditorStart } from '../../data_view_field_editor/public';
import { DataViewEditorStart } from '../../data_view_editor/public';
-import { setTheme } from '.';
export interface IndexPatternManagementSetupDependencies {
management: ManagementSetup;
@@ -55,7 +54,6 @@ export class IndexPatternManagementPlugin
{ management, urlForwarding }: IndexPatternManagementSetupDependencies
) {
const kibanaSection = management.sections.section.kibana;
- setTheme(core.theme);
if (!kibanaSection) {
throw new Error('`kibana` management section not found.');
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index 8cf1269b982a1..c6beccd5e3365 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -10,8 +10,6 @@ import './index.scss';
import { PluginInitializerContext } from 'src/core/public';
import { EmbeddablePublicPlugin } from './plugin';
-import type { ThemeServiceStart } from '../../../core/public';
-import { createGetterSetter } from '../../../plugins/kibana_utils/public';
export type {
Adapters,
@@ -85,8 +83,6 @@ export function plugin(initializerContext: PluginInitializerContext) {
return new EmbeddablePublicPlugin(initializerContext);
}
-export const [getTheme, setTheme] = createGetterSetter('Theme');
-
export type {
EmbeddableSetup,
EmbeddableStart,
diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
index 7f10776e75653..70c30d314fc82 100644
--- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
@@ -13,7 +13,7 @@ import { KibanaThemeProvider, Markdown } from '../../../../kibana_react/public';
import { Embeddable } from './embeddable';
import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable';
import { IContainer } from '../containers';
-import { getTheme } from '../..';
+import { getTheme } from '../../services';
export const ERROR_EMBEDDABLE_TYPE = 'error';
@@ -44,7 +44,6 @@ export class ErrorEmbeddable extends Embeddable
diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
index 8c09e9d741e79..2e501984dfa76 100644
--- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
+++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
@@ -12,7 +12,7 @@ import React from 'react';
import { Subscription } from 'rxjs';
import deepEqual from 'fast-deep-equal';
import { buildContextMenuForActions, UiActionsService, Action } from '../ui_actions';
-import { CoreStart, OverlayStart } from '../../../../../core/public';
+import { CoreStart, OverlayStart, ThemeServiceStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
import { UsageCollectionStart } from '../../../../usage_collection/public';
@@ -42,7 +42,6 @@ import { CustomizePanelModal } from './panel_header/panel_actions/customize_titl
import { EmbeddableStart } from '../../plugin';
import { EmbeddableErrorLabel } from './embeddable_error_label';
import { EmbeddableStateTransfer, ErrorEmbeddable } from '..';
-import { getTheme } from '../..';
const sortByOrderField = (
{ order: orderA }: { order?: number },
@@ -84,6 +83,7 @@ interface Props {
showBadges?: boolean;
showNotifications?: boolean;
containerContext?: EmbeddableContainerContext;
+ theme: ThemeServiceStart;
}
interface State {
@@ -348,8 +348,7 @@ export class EmbeddablePanel extends React.Component {
) {
return actions;
}
-
- const createGetUserData = (overlays: OverlayStart) =>
+ const createGetUserData = (overlays: OverlayStart, theme: ThemeServiceStart) =>
async function getUserData(context: { embeddable: IEmbeddable }) {
return new Promise<{ title: string | undefined; hideTitle?: boolean }>((resolve) => {
const session = overlays.openModal(
@@ -362,7 +361,7 @@ export class EmbeddablePanel extends React.Component {
}}
cancel={() => session.close()}
/>,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
{
'data-test-subj': 'customizePanel',
@@ -375,13 +374,16 @@ export class EmbeddablePanel extends React.Component {
// registry.
return {
...actions,
- customizePanelTitle: new CustomizePanelTitleAction(createGetUserData(this.props.overlays)),
+ customizePanelTitle: new CustomizePanelTitleAction(
+ createGetUserData(this.props.overlays, this.props.theme)
+ ),
addPanel: new AddPanelAction(
this.props.getEmbeddableFactory,
this.props.getAllEmbeddableFactories,
this.props.overlays,
this.props.notifications,
this.props.SavedObjectFinder,
+ this.props.theme,
this.props.reportUiCounter
),
removePanel: new RemovePanelAction(),
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
index 224cb80478769..fe6a9ea3c22b3 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx
@@ -16,7 +16,7 @@ import {
} from '../../../../test_samples/embeddables/filterable_embeddable';
import { FilterableEmbeddableFactory } from '../../../../test_samples/embeddables/filterable_embeddable_factory';
import { FilterableContainer } from '../../../../test_samples/embeddables/filterable_container';
-import { coreMock } from '../../../../../../../../core/public/mocks';
+import { coreMock, themeServiceMock } from '../../../../../../../../core/public/mocks';
import { ContactCardEmbeddable } from '../../../../test_samples';
import { EmbeddableStart } from '../../../../../plugin';
import { embeddablePluginMock } from '../../../../../mocks';
@@ -25,6 +25,7 @@ import { defaultTrigger } from '../../../../../../../ui_actions/public/triggers'
const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(FILTERABLE_EMBEDDABLE, new FilterableEmbeddableFactory());
const getFactory = doStart().getEmbeddableFactory;
+const theme = themeServiceMock.createStartContract();
let container: FilterableContainer;
let embeddable: FilterableEmbeddable;
@@ -37,7 +38,8 @@ beforeEach(async () => {
() => [] as any,
start.overlays,
start.notifications,
- () => null
+ () => null,
+ theme
);
const derivedFilter: MockFilter = {
@@ -72,7 +74,8 @@ test('Is not compatible when container is in view mode', async () => {
() => [] as any,
start.overlays,
start.notifications,
- () => null
+ () => null,
+ theme
);
container.updateInput({ viewMode: ViewMode.VIEW });
expect(
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.ts b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.ts
index 49be1c3ce0123..d766c509782a0 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.ts
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.ts
@@ -8,7 +8,7 @@
import { i18n } from '@kbn/i18n';
import { Action, ActionExecutionContext } from 'src/plugins/ui_actions/public';
-import { NotificationsStart, OverlayStart } from 'src/core/public';
+import { NotificationsStart, OverlayStart, ThemeServiceStart } from 'src/core/public';
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
import { ViewMode } from '../../../../types';
import { openAddPanelFlyout } from './open_add_panel_flyout';
@@ -31,6 +31,7 @@ export class AddPanelAction implements Action {
private readonly overlays: OverlayStart,
private readonly notifications: NotificationsStart,
private readonly SavedObjectFinder: React.ComponentType,
+ private readonly theme: ThemeServiceStart,
private readonly reportUiCounter?: UsageCollectionStart['reportUiCounter']
) {}
@@ -63,6 +64,7 @@ export class AddPanelAction implements Action {
notifications: this.notifications,
SavedObjectFinder: this.SavedObjectFinder,
reportUiCounter: this.reportUiCounter,
+ theme: this.theme,
});
}
}
diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
index 8a648c370d083..00c6f99abda09 100644
--- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
+++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx
@@ -7,13 +7,12 @@
*/
import React from 'react';
-import { NotificationsStart, OverlayRef, OverlayStart } from 'src/core/public';
+import { NotificationsStart, OverlayRef, OverlayStart, ThemeServiceStart } from 'src/core/public';
import { EmbeddableStart } from '../../../../../plugin';
import { toMountPoint } from '../../../../../../../kibana_react/public';
import { IContainer } from '../../../../containers';
import { AddPanelFlyout } from './add_panel_flyout';
import { UsageCollectionStart } from '../../../../../../../usage_collection/public';
-import { getTheme } from '../../../../../';
export function openAddPanelFlyout(options: {
embeddable: IContainer;
@@ -24,6 +23,7 @@ export function openAddPanelFlyout(options: {
SavedObjectFinder: React.ComponentType;
showCreateNewMenu?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
+ theme: ThemeServiceStart;
}): OverlayRef {
const {
embeddable,
@@ -34,6 +34,7 @@ export function openAddPanelFlyout(options: {
SavedObjectFinder,
showCreateNewMenu,
reportUiCounter,
+ theme,
} = options;
const flyoutSession = overlays.openFlyout(
toMountPoint(
@@ -51,7 +52,7 @@ export function openAddPanelFlyout(options: {
SavedObjectFinder={SavedObjectFinder}
showCreateNewMenu={showCreateNewMenu}
/>,
- { theme$: getTheme().theme$ }
+ { theme$: theme.theme$ }
),
{
'data-test-subj': 'dashboardAddPanel',
diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx
index e78937a9caebd..041207f2f2380 100644
--- a/src/plugins/embeddable/public/plugin.tsx
+++ b/src/plugins/embeddable/public/plugin.tsx
@@ -52,7 +52,7 @@ import {
getTelemetryFunction,
} from '../common/lib';
import { getAllMigrations } from '../common/lib/get_all_migrations';
-import { setTheme } from '.';
+import { setTheme } from './services';
export interface EmbeddableSetupDependencies {
uiActions: UiActionsSetup;
@@ -120,8 +120,8 @@ export class EmbeddablePublicPlugin implements Plugin {
this.appList = appList;
@@ -187,6 +186,7 @@ export class EmbeddablePublicPlugin implements Plugin
);
diff --git a/src/plugins/embeddable/public/services.ts b/src/plugins/embeddable/public/services.ts
new file mode 100644
index 0000000000000..96088e086a771
--- /dev/null
+++ b/src/plugins/embeddable/public/services.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ThemeServiceSetup } from 'src/core/public';
+import { createGetterSetter } from '../../kibana_utils/public';
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx
index 8763c2f3ed87d..237e71009d205 100644
--- a/src/plugins/share/public/services/share_menu_manager.tsx
+++ b/src/plugins/share/public/services/share_menu_manager.tsx
@@ -10,9 +10,8 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { I18nProvider } from '@kbn/i18n-react';
import { EuiWrappingPopover } from '@elastic/eui';
-import { Observable } from 'rxjs';
-import { CoreStart, CoreTheme, HttpStart } from 'kibana/public';
+import { CoreStart, HttpStart, ThemeServiceStart } from 'kibana/public';
import { KibanaThemeProvider } from '../../../kibana_react/public';
import { ShareContextMenu } from '../components/share_context_menu';
import { ShareMenuItem, ShowShareMenuOptions } from '../types';
@@ -44,7 +43,7 @@ export class ShareMenuManager {
post: core.http.post,
basePath: core.http.basePath.get(),
anonymousAccess,
- theme$: core.theme.theme$,
+ theme: core.theme,
});
},
};
@@ -68,14 +67,14 @@ export class ShareMenuManager {
basePath,
embedUrlParamExtensions,
anonymousAccess,
- theme$,
+ theme,
showPublicUrlSwitch,
}: ShowShareMenuOptions & {
menuItems: ShareMenuItem[];
post: HttpStart['post'];
basePath: string;
anonymousAccess: AnonymousAccessServiceContract | undefined;
- theme$: Observable;
+ theme: ThemeServiceStart;
}) {
if (this.isOpen) {
this.onClose();
@@ -87,7 +86,7 @@ export class ShareMenuManager {
document.body.appendChild(this.container);
const element = (
-
+
;
- theme$: Observable;
+ theme: ThemeServiceSetup;
}
-export const Page: React.FC = ({ manager, theme$ }) => {
+export const Page: React.FC = ({ manager, theme }) => {
const error = useObservable(manager.error$);
if (error) {
return (
-
+
= ({ manager, theme$ }) => {
}
return (
-
+
{
const { render } = await import('./render');
- const theme$ = params.theme$;
- const unmount = render(params.element, { manager: this, theme$ });
+ const unmount = render(params.element, { manager: this, theme: core.theme });
this.onMount(params.history.location.search);
return () => {
unmount();
diff --git a/src/plugins/share/public/url_service/redirect/render.ts b/src/plugins/share/public/url_service/redirect/render.ts
index 7ad74ab419067..2b9c3a50758e4 100644
--- a/src/plugins/share/public/url_service/redirect/render.ts
+++ b/src/plugins/share/public/url_service/redirect/render.ts
@@ -11,7 +11,7 @@ import * as ReactDOM from 'react-dom';
import { Page, PageProps } from './components/page';
export const render = (container: HTMLElement, props: PageProps) => {
- ReactDOM.render(React.createElement(Page, { ...props }), container);
+ ReactDOM.render(React.createElement(Page, props), container);
return () => {
ReactDOM.unmountComponentAtNode(container);
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 52c092610ce93..04449d7b656bc 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
@@ -12,7 +12,7 @@ import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiPopover } from '@elas
import { EventEmitter } from 'events';
import ReactDOM from 'react-dom';
import { KibanaThemeProvider } from '../../../kibana_react/public';
-import { getTheme } from '../index';
+import { getTheme } from '../services';
let activeSession: ContextMenuSession | null = null;
diff --git a/src/plugins/ui_actions/public/index.ts b/src/plugins/ui_actions/public/index.ts
index 6e138da2d6cd2..a93b5e3f958a9 100644
--- a/src/plugins/ui_actions/public/index.ts
+++ b/src/plugins/ui_actions/public/index.ts
@@ -7,16 +7,12 @@
*/
import { PluginInitializerContext } from '../../../core/public';
-import type { ThemeServiceStart } from '../../../core/public';
import { UiActionsPlugin } from './plugin';
-import { createGetterSetter } from '../../../plugins/kibana_utils/public';
export function plugin(initializerContext: PluginInitializerContext) {
return new UiActionsPlugin(initializerContext);
}
-export const [getTheme, setTheme] = createGetterSetter('Theme');
-
export type { UiActionsSetup, UiActionsStart } from './plugin';
export type { UiActionsServiceParams } from './service';
export { UiActionsService } from './service';
diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts
index a95b45900c748..2a2ad100a53d3 100644
--- a/src/plugins/ui_actions/public/plugin.ts
+++ b/src/plugins/ui_actions/public/plugin.ts
@@ -10,7 +10,7 @@ import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core
import { PublicMethodsOf } from '@kbn/utility-types';
import { UiActionsService } from './service';
import { rowClickTrigger, visualizeFieldTrigger, visualizeGeoFieldTrigger } from './triggers';
-import { setTheme } from '.';
+import { setTheme } from './services';
export type UiActionsSetup = Pick<
UiActionsService,
diff --git a/src/plugins/ui_actions/public/services.ts b/src/plugins/ui_actions/public/services.ts
new file mode 100644
index 0000000000000..96088e086a771
--- /dev/null
+++ b/src/plugins/ui_actions/public/services.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ThemeServiceSetup } from 'src/core/public';
+import { createGetterSetter } from '../../kibana_utils/public';
+
+export const [getTheme, setTheme] = createGetterSetter('Theme');
diff --git a/x-pack/examples/reporting_example/public/application.tsx b/x-pack/examples/reporting_example/public/application.tsx
index 5420d8853259a..9b044ac801773 100644
--- a/x-pack/examples/reporting_example/public/application.tsx
+++ b/x-pack/examples/reporting_example/public/application.tsx
@@ -22,10 +22,9 @@ export const renderApp = (
{ appBasePath, element, history }: AppMountParameters, // FIXME: appBasePath is deprecated
forwardedParams: MyForwardableState
) => {
- const theme$ = coreStart.theme.theme$;
ReactDOM.render(
-
+
} />
From bbaf9909bf13dcec3cdacfafae6d995e30345324 Mon Sep 17 00:00:00 2001
From: shivindera
Date: Mon, 10 Jan 2022 13:33:15 +0100
Subject: [PATCH 7/7] fix for broken Embeddable Panel
---
.../embeddable/dashboard_container.test.tsx | 4 +++-
.../public/application/top_nav/dashboard_top_nav.tsx | 2 ++
.../public/lib/panel/embeddable_panel.test.tsx | 12 +++++++++++-
src/plugins/embeddable/public/mocks.tsx | 5 ++++-
.../lens/public/embeddable/embeddable_component.tsx | 7 ++++++-
5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
index d5eef0c05129d..5f50cfd842b67 100644
--- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
@@ -41,6 +41,7 @@ import { uiActionsPluginMock } from '../../../../ui_actions/public/mocks';
import { getStubPluginServices } from '../../../../presentation_util/public';
const presentationUtil = getStubPluginServices();
+const theme = coreMock.createStart().theme;
const options: DashboardContainerServices = {
// TODO: clean up use of any
@@ -55,7 +56,7 @@ const options: DashboardContainerServices = {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
- theme: coreMock.createStart().theme,
+ theme,
presentationUtil,
};
@@ -251,6 +252,7 @@ test('DashboardContainer in edit mode shows edit mode actions', async () => {
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
diff --git a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
index bc5bb3aa4a566..005d40a90f38f 100644
--- a/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
+++ b/src/plugins/dashboard/public/application/top_nav/dashboard_top_nav.tsx
@@ -161,6 +161,7 @@ export function DashboardTopNav({
overlays: core.overlays,
SavedObjectFinder: getSavedObjectFinder(core.savedObjects, uiSettings),
reportUiCounter: usageCollection?.reportUiCounter,
+ theme: core.theme,
}),
}));
}
@@ -171,6 +172,7 @@ export function DashboardTopNav({
core.notifications,
core.savedObjects,
core.overlays,
+ core.theme,
uiSettings,
usageCollection,
]);
diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx
index 78bd337b21e52..8d313030556c6 100644
--- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx
+++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx
@@ -31,7 +31,7 @@ import {
import { inspectorPluginMock } from '../../../../inspector/public/mocks';
import { EuiBadge } from '@elastic/eui';
import { embeddablePluginMock } from '../../mocks';
-import { applicationServiceMock } from '../../../../../core/public/mocks';
+import { applicationServiceMock, themeServiceMock } from '../../../../../core/public/mocks';
const actionRegistry = new Map();
const triggerRegistry = new Map();
@@ -44,6 +44,7 @@ const trigger: Trigger = {
};
const embeddableFactory = new ContactCardEmbeddableFactory((() => null) as any, {} as any);
const applicationMock = applicationServiceMock.createStartContract();
+const theme = themeServiceMock.createStartContract();
actionRegistry.set(editModeAction.id, editModeAction);
triggerRegistry.set(trigger.id, trigger);
@@ -152,6 +153,7 @@ test('HelloWorldContainer in view mode hides edit mode actions', async () => {
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -191,6 +193,7 @@ const renderInEditModeAndOpenContextMenu = async (
application={applicationMock}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -298,6 +301,7 @@ test('HelloWorldContainer in edit mode shows edit mode actions', async () => {
application={applicationMock}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -360,6 +364,7 @@ test('Panel title customize link does not exist in view mode', async () => {
application={applicationMock}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -395,6 +400,7 @@ test('Runs customize panel action on title click when in edit mode', async () =>
application={applicationMock}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -443,6 +449,7 @@ test('Updates when hidePanelTitles is toggled', async () => {
application={applicationMock}
inspector={inspector}
SavedObjectFinder={() => null}
+ theme={theme}
/>
);
@@ -497,6 +504,7 @@ test('Check when hide header option is false', async () => {
inspector={inspector}
SavedObjectFinder={() => null}
hideHeader={false}
+ theme={theme}
/>
);
@@ -535,6 +543,7 @@ test('Check when hide header option is true', async () => {
inspector={inspector}
SavedObjectFinder={() => null}
hideHeader={true}
+ theme={theme}
/>
);
@@ -567,6 +576,7 @@ test('Should work in minimal way rendering only the inspector action', async ()
getActions={() => Promise.resolve([])}
inspector={inspector}
hideHeader={false}
+ theme={theme}
/>
);
diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx
index 94eb5e5cc6a02..44d2b395a48c3 100644
--- a/src/plugins/embeddable/public/mocks.tsx
+++ b/src/plugins/embeddable/public/mocks.tsx
@@ -20,7 +20,7 @@ import {
ReferenceOrValueEmbeddable,
} from '.';
import { EmbeddablePublicPlugin } from './plugin';
-import { coreMock } from '../../../core/public/mocks';
+import { coreMock, themeServiceMock } from '../../../core/public/mocks';
import { UiActionsService } from './lib/ui_actions';
import { CoreStart } from '../../../core/public';
import { Start as InspectorStart } from '../../inspector/public';
@@ -43,6 +43,8 @@ interface CreateEmbeddablePanelMockArgs {
SavedObjectFinder: React.ComponentType;
}
+const theme = themeServiceMock.createStartContract();
+
export const createEmbeddablePanelMock = ({
getActions,
getEmbeddableFactory,
@@ -64,6 +66,7 @@ export const createEmbeddablePanelMock = ({
overlays={overlays || ({} as any)}
inspector={inspector || ({} as any)}
SavedObjectFinder={SavedObjectFinder || (() => null)}
+ theme={theme}
/>
);
};
diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx
index 7f65e50bf4429..e501138648b14 100644
--- a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx
+++ b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx
@@ -6,7 +6,7 @@
*/
import React, { FC, useEffect } from 'react';
-import type { CoreStart } from 'kibana/public';
+import type { CoreStart, ThemeServiceStart } from 'kibana/public';
import type { UiActionsStart } from 'src/plugins/ui_actions/public';
import type { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { EuiLoadingChart } from '@elastic/eui';
@@ -68,6 +68,7 @@ export function getEmbeddableComponent(core: CoreStart, plugins: PluginsStartDep
const input = { ...props };
const [embeddable, loading, error] = useEmbeddableFactory({ factory, input });
const hasActions = props.withActions === true;
+ const theme = core.theme;
if (loading) {
return ;
@@ -81,6 +82,7 @@ export function getEmbeddableComponent(core: CoreStart, plugins: PluginsStartDep
inspector={inspector}
actionPredicate={() => hasActions}
input={input}
+ theme={theme}
/>
);
}
@@ -95,6 +97,7 @@ interface EmbeddablePanelWrapperProps {
inspector: PluginsStartDependencies['inspector'];
actionPredicate: (id: string) => boolean;
input: EmbeddableComponentProps;
+ theme: ThemeServiceStart;
}
const EmbeddablePanelWrapper: FC = ({
@@ -103,6 +106,7 @@ const EmbeddablePanelWrapper: FC = ({
actionPredicate,
inspector,
input,
+ theme,
}) => {
useEffect(() => {
embeddable.updateInput(input);
@@ -118,6 +122,7 @@ const EmbeddablePanelWrapper: FC = ({
showShadow={false}
showBadges={false}
showNotifications={false}
+ theme={theme}
/>
);
};