[8.10] [ML] Fixes dark mode in flyouts and modals (#164399) (#164559)

# Backport

This will backport the following commits from `main` to `8.10`:
- [[ML] Fixes dark mode in flyouts and modals
(#164399)](https://github.com/elastic/kibana/pull/164399)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"James
Gowdy","email":"jgowdy@elastic.co"},"sourceCommit":{"committedDate":"2023-08-23T10:47:18Z","message":"[ML]
Fixes dark mode in flyouts and modals (#164399)\n\nA recent EUI change
has caused a problem with the theme when using the\r\ndeprecated
`toMountPoint` inside `overlays.openFlyout` to
create\r\nflyouts.\r\nThis causes the contents of the rendered flyout to
not know the current\r\ntheme, this is obvious when running in dark
mode.\r\n\r\nThe fix is to switch to the non-deprecated version of
`toMountPoint`.\r\n\r\nFlyouts:\r\nCreate anomaly detection job from
Lens flyout in Dashboard.\r\nAnomaly swim lane and anomaly chart job
embeddables job selection flyout\r\nin Dashboard.\r\nLog pattern
analysis flyout in Discover.\r\n\r\nModals:\r\nTrained models start
deployment modal.\r\nTrained models force stop deployment
modal.\r\nTrained models stop deployment modal when there are
multiple\r\ndeployments.\r\n\r\nMisc:\r\nPage not found banner.\r\nJobs
list header, which contains the settings button.\r\nDFA clone job
warning toast when the original data view no
longer\r\nexists.\r\nComponents in ml's date picker package\r\n\r\nFixes
https://github.com/elastic/kibana/issues/164379\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Dima Arnautov
<arnautov.dima@gmail.com>","sha":"af440aae4b55e3090dc6a7983105fd98e16402ab","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["non-issue",":ml","release_note:skip","Feature:ML/AIOps","v8.10.0","v8.11.0"],"number":164399,"url":"https://github.com/elastic/kibana/pull/164399","mergeCommit":{"message":"[ML]
Fixes dark mode in flyouts and modals (#164399)\n\nA recent EUI change
has caused a problem with the theme when using the\r\ndeprecated
`toMountPoint` inside `overlays.openFlyout` to
create\r\nflyouts.\r\nThis causes the contents of the rendered flyout to
not know the current\r\ntheme, this is obvious when running in dark
mode.\r\n\r\nThe fix is to switch to the non-deprecated version of
`toMountPoint`.\r\n\r\nFlyouts:\r\nCreate anomaly detection job from
Lens flyout in Dashboard.\r\nAnomaly swim lane and anomaly chart job
embeddables job selection flyout\r\nin Dashboard.\r\nLog pattern
analysis flyout in Discover.\r\n\r\nModals:\r\nTrained models start
deployment modal.\r\nTrained models force stop deployment
modal.\r\nTrained models stop deployment modal when there are
multiple\r\ndeployments.\r\n\r\nMisc:\r\nPage not found banner.\r\nJobs
list header, which contains the settings button.\r\nDFA clone job
warning toast when the original data view no
longer\r\nexists.\r\nComponents in ml's date picker package\r\n\r\nFixes
https://github.com/elastic/kibana/issues/164379\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Dima Arnautov
<arnautov.dima@gmail.com>","sha":"af440aae4b55e3090dc6a7983105fd98e16402ab"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164399","number":164399,"mergeCommit":{"message":"[ML]
Fixes dark mode in flyouts and modals (#164399)\n\nA recent EUI change
has caused a problem with the theme when using the\r\ndeprecated
`toMountPoint` inside `overlays.openFlyout` to
create\r\nflyouts.\r\nThis causes the contents of the rendered flyout to
not know the current\r\ntheme, this is obvious when running in dark
mode.\r\n\r\nThe fix is to switch to the non-deprecated version of
`toMountPoint`.\r\n\r\nFlyouts:\r\nCreate anomaly detection job from
Lens flyout in Dashboard.\r\nAnomaly swim lane and anomaly chart job
embeddables job selection flyout\r\nin Dashboard.\r\nLog pattern
analysis flyout in Discover.\r\n\r\nModals:\r\nTrained models start
deployment modal.\r\nTrained models force stop deployment
modal.\r\nTrained models stop deployment modal when there are
multiple\r\ndeployments.\r\n\r\nMisc:\r\nPage not found banner.\r\nJobs
list header, which contains the settings button.\r\nDFA clone job
warning toast when the original data view no
longer\r\nexists.\r\nComponents in ml's date picker package\r\n\r\nFixes
https://github.com/elastic/kibana/issues/164379\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Dima Arnautov
<arnautov.dima@gmail.com>","sha":"af440aae4b55e3090dc6a7983105fd98e16402ab"}}]}]
BACKPORT-->

Co-authored-by: James Gowdy <jgowdy@elastic.co>
This commit is contained in:
Kibana Machine 2023-08-23 08:00:27 -04:00 committed by GitHub
parent 79136c28dc
commit 109b4b6926
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 247 additions and 304 deletions

View file

@ -77,8 +77,7 @@ const mockContextFactory = (addWarning: jest.Mock<void, []>) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { of } = require('rxjs');
const mockedUiSettingsKeys = {} as typeof UI_SETTINGS;
const mockedToMountPoint = jest.fn();
const mockedWrapWithTheme = jest.fn();
const mockedI18n = jest.fn();
return () => ({
notifications: {
@ -121,8 +120,7 @@ const mockContextFactory = (addWarning: jest.Mock<void, []>) => {
theme$: of(),
},
uiSettingsKeys: mockedUiSettingsKeys,
toMountPoint: mockedToMountPoint,
wrapWithTheme: mockedWrapWithTheme,
i18n: mockedI18n,
});
};

View file

@ -25,6 +25,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { TimeHistoryContract } from '@kbn/data-plugin/public';
import { useUrlState } from '@kbn/ml-url-state';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { useRefreshIntervalUpdates, useTimeRangeUpdates } from '../hooks/use_timefilter';
import { useDatePickerContext } from '../hooks/use_date_picker_context';
@ -103,11 +104,10 @@ export const DatePickerWrapper: FC<DatePickerWrapperProps> = (props) => {
const {
data,
notifications: { toasts },
theme: { theme$ },
uiSettings: config,
uiSettingsKeys,
wrapWithTheme,
toMountPoint,
theme,
i18n: i18nStart,
} = useDatePickerContext();
const isWithinLBreakpoint = useIsWithinMaxBreakpoint('l');
@ -184,23 +184,21 @@ export const DatePickerWrapper: FC<DatePickerWrapperProps> = (props) => {
'The refresh interval in Advanced Settings is shorter than the minimum supported interval.',
}),
text: toMountPoint(
wrapWithTheme(
<EuiButton
onClick={setRefreshInterval.bind(null, {
pause: refreshInterval.pause,
value: DEFAULT_REFRESH_INTERVAL_MS,
})}
>
<FormattedMessage
id="xpack.ml.datePicker.pageRefreshResetButton"
defaultMessage="Set to {defaultInterval}"
values={{
defaultInterval: `${DEFAULT_REFRESH_INTERVAL_MS / 1000}s`,
}}
/>
</EuiButton>,
theme$
)
<EuiButton
onClick={setRefreshInterval.bind(null, {
pause: refreshInterval.pause,
value: DEFAULT_REFRESH_INTERVAL_MS,
})}
>
<FormattedMessage
id="xpack.ml.datePicker.pageRefreshResetButton"
defaultMessage="Set to {defaultInterval}"
values={{
defaultInterval: `${DEFAULT_REFRESH_INTERVAL_MS / 1000}s`,
}}
/>
</EuiButton>,
{ theme, i18n: i18nStart }
),
},
{ toastLifeTimeMs: 30000 }

View file

@ -9,9 +9,8 @@ import React, { createContext, useContext, type FC } from 'react';
import type { UI_SETTINGS } from '@kbn/data-plugin/common';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { CoreSetup, IUiSettingsClient, ThemeServiceStart } from '@kbn/core/public';
import type { CoreSetup, I18nStart, IUiSettingsClient, ThemeServiceStart } from '@kbn/core/public';
import type { HttpStart } from '@kbn/core/public';
import type { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
/**
* Date Picker Dependencies to be passed on via `DatePickerContextProvider`.
@ -42,13 +41,9 @@ export interface DatePickerDependencies {
*/
uiSettingsKeys: typeof UI_SETTINGS;
/**
* helper to be used with notifications.
* Internationalisation service
*/
wrapWithTheme: typeof wrapWithTheme;
/**
* helper to be used with notifications.
*/
toMountPoint: typeof toMountPoint;
i18n: I18nStart;
}
/**

View file

@ -25,7 +25,7 @@
"@kbn/core",
"@kbn/data-views-plugin",
"@kbn/ml-is-populated-object",
"@kbn/kibana-react-plugin",
"@kbn/ml-query-utils",
"@kbn/react-kibana-mount",
]
}

View file

@ -18,7 +18,6 @@ import { UrlStateProvider } from '@kbn/ml-url-state';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { DatePickerContextProvider, mlTimefilterRefresh$ } from '@kbn/ml-date-picker';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { type Observable } from 'rxjs';
import { DataSourceContext } from '../../hooks/use_data_source';
@ -55,9 +54,7 @@ export const ChangePointDetectionAppState: FC<ChangePointDetectionAppStateProps>
appDependencies,
}) => {
const datePickerDeps = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -14,7 +14,6 @@ import { UrlStateProvider } from '@kbn/ml-url-state';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { DataSourceContext } from '../../hooks/use_data_source';
import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context';
@ -52,9 +51,7 @@ export const LogCategorizationAppState: FC<LogCategorizationAppStateProps> = ({
}
const datePickerDeps = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -12,14 +12,11 @@ import { pick } from 'lodash';
import type { CoreStart } from '@kbn/core/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import {
toMountPoint,
wrapWithTheme,
KibanaContextProvider,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import type { DataViewField, DataView } from '@kbn/data-views-plugin/common';
import { UI_SETTINGS } from '@kbn/data-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { DatePickerContextProvider, type DatePickerDependencies } from '@kbn/ml-date-picker';
import { StorageContextProvider } from '@kbn/ml-local-storage';
import type { AiopsPluginStartDeps } from '../../types';
import { AiopsAppContext } from '../../hooks/use_aiops_app_context';
@ -34,7 +31,7 @@ export async function showCategorizeFlyout(
coreStart: CoreStart,
plugins: AiopsPluginStartDeps
): Promise<void> {
const { http, theme, overlays, application, notifications, uiSettings } = coreStart;
const { http, theme, overlays, application, notifications, uiSettings, i18n } = coreStart;
return new Promise(async (resolve, reject) => {
try {
@ -49,38 +46,36 @@ export async function showCategorizeFlyout(
http,
theme,
application,
i18n,
...plugins,
};
const datePickerDeps = {
const datePickerDeps: DatePickerDependencies = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
i18n,
uiSettingsKeys: UI_SETTINGS,
};
const flyoutSession = overlays.openFlyout(
toMountPoint(
wrapWithTheme(
<KibanaContextProvider
services={{
...coreStart,
}}
>
<AiopsAppContext.Provider value={appDependencies}>
<DatePickerContextProvider {...datePickerDeps}>
<StorageContextProvider storage={localStorage} storageKeys={AIOPS_STORAGE_KEYS}>
<LogCategorizationFlyout
dataView={dataView}
savedSearch={null}
selectedField={field}
onClose={onFlyoutClose}
/>
</StorageContextProvider>
</DatePickerContextProvider>
</AiopsAppContext.Provider>
</KibanaContextProvider>,
theme.theme$
)
<KibanaContextProvider
services={{
...coreStart,
}}
>
<AiopsAppContext.Provider value={appDependencies}>
<DatePickerContextProvider {...datePickerDeps}>
<StorageContextProvider storage={localStorage} storageKeys={AIOPS_STORAGE_KEYS}>
<LogCategorizationFlyout
dataView={dataView}
savedSearch={null}
selectedField={field}
onClose={onFlyoutClose}
/>
</StorageContextProvider>
</DatePickerContextProvider>
</AiopsAppContext.Provider>
</KibanaContextProvider>,
{ theme, i18n }
),
{
'data-test-subj': 'aiopsCategorizeFlyout',

View file

@ -15,7 +15,6 @@ import { UrlStateProvider } from '@kbn/ml-url-state';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context';
import { AiopsAppContext } from '../../hooks/use_aiops_app_context';
@ -58,9 +57,7 @@ export const LogRateAnalysisAppState: FC<LogRateAnalysisAppStateProps> = ({
}
const datePickerDeps = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -18,7 +18,6 @@ import { UrlStateProvider } from '@kbn/ml-url-state';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { timeSeriesDataViewWarning } from '../../../application/utils/time_series_dataview_check';
import { AiopsAppContext, type AiopsAppDependencies } from '../../../hooks/use_aiops_app_context';
@ -81,9 +80,7 @@ export const LogRateAnalysisContentWrapper: FC<LogRateAnalysisContentWrapperProp
}
const datePickerDeps = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -13,7 +13,7 @@ import {
EmbeddableOutput,
IContainer,
} from '@kbn/embeddable-plugin/public';
import { KibanaThemeProvider, toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { ThemeServiceStart } from '@kbn/core-theme-browser';
import { DataPublicPluginStart, UI_SETTINGS } from '@kbn/data-plugin/public';
import { type CoreStart, IUiSettingsClient } from '@kbn/core/public';
@ -95,9 +95,7 @@ export class EmbeddableChangePointChart extends AbstractEmbeddable<
const I18nContext = this.deps.i18n.Context;
const datePickerDeps = {
...pick(this.deps, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(this.deps, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -92,6 +92,10 @@ export interface AiopsAppDependencies {
* Used to create lens embeddables.
*/
lens: LensPublicStart;
/**
* Internationalisation service
*/
i18n: CoreStart['i18n'];
/**
* Deps for unified fields stats.
*/

View file

@ -15,12 +15,7 @@ import { UrlStateProvider } from '@kbn/ml-url-state';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import {
KibanaContextProvider,
KibanaThemeProvider,
toMountPoint,
wrapWithTheme,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { DV_STORAGE_KEYS } from '../index_data_visualizer/types/storage';
import { getCoreStart, getPluginsStart } from '../../kibana_services';
@ -77,9 +72,7 @@ export const DataComparisonDetectionAppState: FC<DataComparisonDetectionAppState
...coreStart,
};
const datePickerDeps = {
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -22,7 +22,6 @@ import {
IContainer,
} from '@kbn/embeddable-plugin/public';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import type { Query } from '@kbn/es-query';
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
@ -221,9 +220,7 @@ export class DataVisualizerGridEmbeddable extends Embeddable<
const services = { ...this.services[0], ...this.services[1] };
const datePickerDeps = {
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -13,12 +13,7 @@ import { isEqual } from 'lodash';
import { encode } from '@kbn/rison';
import { i18n } from '@kbn/i18n';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import {
KibanaContextProvider,
KibanaThemeProvider,
toMountPoint,
wrapWithTheme,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { StorageContextProvider } from '@kbn/ml-local-storage';
import { DataView } from '@kbn/data-views-plugin/public';
import { getNestedProperty } from '@kbn/ml-nested-property';
@ -302,9 +297,7 @@ export const IndexDataVisualizer: FC<{
...coreStart,
};
const datePickerDeps = {
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -6,7 +6,6 @@
*/
import React, { FC, useEffect, useMemo, useState } from 'react';
import { pick, orderBy } from 'lodash';
import moment from 'moment';
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui';
@ -29,6 +28,7 @@ import {
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
import { i18n } from '@kbn/i18n';
import { ALERT_END } from '@kbn/rule-data-utils';
import { pick, orderBy } from 'lodash';
import { Color, colorTransformer } from '../../../../../../common/color_palette';
import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana';
import {
@ -289,6 +289,7 @@ export const LogRateAnalysis: FC<AlertDetailsLogRateAnalysisSectionProps> = ({ r
'unifiedSearch',
'theme',
'lens',
'i18n',
])}
/>
</EuiFlexItem>

View file

@ -63,6 +63,7 @@ export const ChangePointDetectionPage: FC = () => {
'presentationUtil',
'embeddable',
'cases',
'i18n',
]),
fieldStats: { useFieldStatsTrigger, FieldStatsFlyoutProvider },
}}

View file

@ -54,6 +54,7 @@ export const LogCategorizationPage: FC = () => {
'unifiedSearch',
'theme',
'lens',
'i18n',
])}
/>
)}

View file

@ -57,6 +57,7 @@ export const LogRateAnalysisPage: FC = () => {
'unifiedSearch',
'theme',
'lens',
'i18n',
])}
/>
)}

View file

@ -15,12 +15,7 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import { DatePickerContextProvider } from '@kbn/ml-date-picker';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import {
KibanaContextProvider,
KibanaThemeProvider,
toMountPoint,
wrapWithTheme,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { StorageContextProvider } from '@kbn/ml-local-storage';
import useLifecycles from 'react-use/lib/useLifecycles';
import useObservable from 'react-use/lib/useObservable';
@ -128,9 +123,7 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
if (!licenseReady || !mlCapabilities) return null;
const datePickerDeps = {
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(services, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};

View file

@ -7,7 +7,8 @@
import React, { FC, ReactNode, useContext, useEffect, useMemo } from 'react';
import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';
import { KibanaContextProvider, toMountPoint } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { useMlKibana } from '../../contexts/kibana';
import { MlPageControlsContext } from '../ml_page';
@ -17,6 +18,7 @@ export interface HeaderMenuPortalProps {
export const HeaderMenuPortal: FC<HeaderMenuPortalProps> = ({ children }) => {
const { services } = useMlKibana();
const { theme, i18n } = services;
const { setHeaderActionMenu } = useContext(MlPageControlsContext);
@ -32,7 +34,7 @@ export const HeaderMenuPortal: FC<HeaderMenuPortalProps> = ({ children }) => {
<KibanaContextProvider services={services}>
<OutPortal node={portalNode} />
</KibanaContextProvider>,
{ theme$: services.theme.theme$ }
{ theme, i18n }
);
return mount(element);
});

View file

@ -10,7 +10,6 @@ import React, { FC } from 'react';
import { cloneDeep, isEqual } from 'lodash';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { extractErrorMessage } from '@kbn/ml-error-utils';
import {
isClassificationAnalysis,
@ -19,6 +18,7 @@ import {
DEFAULT_RESULTS_FIELD,
type DataFrameAnalyticsConfig,
} from '@kbn/ml-data-frame-analytics-utils';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { DeepReadonly } from '../../../../../../../common/types/common';
import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana';
import { DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES } from '../../hooks/use_create_analytics_form';
@ -414,9 +414,9 @@ export const useNavigateToWizardWithClonedJob = () => {
http: { basePath },
application: { capabilities },
theme,
i18n: i18nStart,
},
} = useMlKibana();
const theme$ = theme.theme$;
const navigateToPath = useNavigateToPath();
const canCreateDataView =
capabilities.savedObjectsManagement.edit === true || capabilities.indexPatterns.save === true;
@ -434,38 +434,36 @@ export const useNavigateToWizardWithClonedJob = () => {
} else {
toasts.addDanger({
title: toMountPoint(
wrapWithTheme(
<>
<FormattedMessage
id="xpack.ml.dataframe.analyticsList.noSourceDataViewForClone"
defaultMessage="Unable to clone the analytics job. No data view exists for index {sourceIndex}."
values={{ sourceIndex }}
/>
{canCreateDataView ? (
<EuiText size="xs" color="text">
<FormattedMessage
id="xpack.ml.dataframe.analytics.cloneAction.dataViewPromptLink"
defaultMessage="{linkToDataViewManagement}"
values={{
linkToDataViewManagement: (
<EuiLink
href={`${basePath.get()}/app/management/kibana/dataViews/create`}
target="_blank"
>
<FormattedMessage
id="xpack.ml.dataframe.analytics.cloneAction.dataViewPromptLinkText"
defaultMessage="Create a data view for {sourceIndex}"
values={{ sourceIndex }}
/>
</EuiLink>
),
}}
/>
</EuiText>
) : null}
</>,
theme$
)
<>
<FormattedMessage
id="xpack.ml.dataframe.analyticsList.noSourceDataViewForClone"
defaultMessage="Unable to clone the analytics job. No data view exists for index {sourceIndex}."
values={{ sourceIndex }}
/>
{canCreateDataView ? (
<EuiText size="xs" color="text">
<FormattedMessage
id="xpack.ml.dataframe.analytics.cloneAction.dataViewPromptLink"
defaultMessage="{linkToDataViewManagement}"
values={{
linkToDataViewManagement: (
<EuiLink
href={`${basePath.get()}/app/management/kibana/dataViews/create`}
target="_blank"
>
<FormattedMessage
id="xpack.ml.dataframe.analytics.cloneAction.dataViewPromptLinkText"
defaultMessage="Create a data view for {sourceIndex}"
values={{ sourceIndex }}
/>
</EuiLink>
),
}}
/>
</EuiText>
) : null}
</>,
{ theme, i18n: i18nStart }
),
});
}

View file

@ -27,11 +27,10 @@ import {
EuiSelect,
EuiSpacer,
} from '@elastic/eui';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import type { Observable } from 'rxjs';
import type { CoreTheme, OverlayStart } from '@kbn/core/public';
import type { I18nStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { css } from '@emotion/react';
import { numberValidator } from '@kbn/ml-agg-utils';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { isCloudTrial } from '../services/ml_server_info';
import {
composeValidators,
@ -497,7 +496,12 @@ export const StartUpdateDeploymentModal: FC<StartDeploymentModalProps> = ({
* @param theme$
*/
export const getUserInputModelDeploymentParamsProvider =
(overlays: OverlayStart, theme$: Observable<CoreTheme>, startModelDeploymentDocUrl: string) =>
(
overlays: OverlayStart,
theme: ThemeServiceStart,
i18nStart: I18nStart,
startModelDeploymentDocUrl: string
) =>
(
model: ModelItem,
initialParams?: ThreadingParams,
@ -507,30 +511,28 @@ export const getUserInputModelDeploymentParamsProvider =
try {
const modalSession = overlays.openModal(
toMountPoint(
wrapWithTheme(
<StartUpdateDeploymentModal
startModelDeploymentDocUrl={startModelDeploymentDocUrl}
initialParams={initialParams}
modelAndDeploymentIds={deploymentIds}
model={model}
onConfigChange={(config) => {
modalSession.close();
<StartUpdateDeploymentModal
startModelDeploymentDocUrl={startModelDeploymentDocUrl}
initialParams={initialParams}
modelAndDeploymentIds={deploymentIds}
model={model}
onConfigChange={(config) => {
modalSession.close();
const resultConfig = { ...config };
if (resultConfig.priority === 'low') {
resultConfig.numOfAllocations = 1;
resultConfig.threadsPerAllocations = 1;
}
const resultConfig = { ...config };
if (resultConfig.priority === 'low') {
resultConfig.numOfAllocations = 1;
resultConfig.threadsPerAllocations = 1;
}
resolve(resultConfig);
}}
onClose={() => {
modalSession.close();
resolve();
}}
/>,
theme$
)
resolve(resultConfig);
}}
onClose={() => {
modalSession.close();
resolve();
}}
/>,
{ theme, i18n: i18nStart }
)
);
} catch (e) {

View file

@ -15,10 +15,10 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import type { OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import type { I18nStart, OverlayStart, ThemeServiceStart } from '@kbn/core/public';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import { isDefined } from '@kbn/ml-is-defined';
import { toMountPoint } from '@kbn/react-kibana-mount';
import type { ModelItem } from './models_list';
interface ForceStopModelConfirmDialogProps {
@ -165,26 +165,24 @@ export const StopModelDeploymentsConfirmDialog: FC<ForceStopModelConfirmDialogPr
};
export const getUserConfirmationProvider =
(overlays: OverlayStart, theme: ThemeServiceStart) =>
(overlays: OverlayStart, theme: ThemeServiceStart, i18nStart: I18nStart) =>
async (forceStopModel: ModelItem): Promise<string[]> => {
return new Promise(async (resolve, reject) => {
try {
const modalSession = overlays.openModal(
toMountPoint(
wrapWithTheme(
<StopModelDeploymentsConfirmDialog
model={forceStopModel}
onCancel={() => {
modalSession.close();
reject();
}}
onConfirm={(deploymentIds: string[]) => {
modalSession.close();
resolve(deploymentIds);
}}
/>,
theme.theme$
)
<StopModelDeploymentsConfirmDialog
model={forceStopModel}
onCancel={() => {
modalSession.close();
reject();
}}
onConfirm={(deploymentIds: string[]) => {
modalSession.close();
resolve(deploymentIds);
}}
/>,
{ theme, i18n: i18nStart }
)
);
} catch (e) {

View file

@ -54,6 +54,7 @@ export function useModelActions({
application: { navigateToUrl, capabilities },
overlays,
theme,
i18n: i18nStart,
docLinks,
mlServices: { mlApiServices },
},
@ -93,14 +94,19 @@ export function useModelActions({
}, [mlApiServices]);
const getUserConfirmation = useMemo(
() => getUserConfirmationProvider(overlays, theme),
[overlays, theme]
() => getUserConfirmationProvider(overlays, theme, i18nStart),
[i18nStart, overlays, theme]
);
const getUserInputModelDeploymentParams = useMemo(
() =>
getUserInputModelDeploymentParamsProvider(overlays, theme.theme$, startModelDeploymentDocUrl),
[overlays, theme.theme$, startModelDeploymentDocUrl]
getUserInputModelDeploymentParamsProvider(
overlays,
theme,
i18nStart,
startModelDeploymentDocUrl
),
[overlays, theme, i18nStart, startModelDeploymentDocUrl]
);
const isBuiltInModel = useCallback(

View file

@ -8,9 +8,10 @@
import { useLocation, useRouteMatch } from 'react-router-dom';
import { keyBy } from 'lodash';
import React, { useEffect, useMemo, useRef } from 'react';
import { toMountPoint, useExecutionContext } from '@kbn/kibana-react-plugin/public';
import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
import { EuiCallOut } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { PLUGIN_ID } from '../../../common/constants/app';
import { useMlKibana } from '../contexts/kibana';
import type { MlRoute } from './router';
@ -23,7 +24,7 @@ export const useActiveRoute = (routesList: MlRoute[]): MlRoute => {
const { pathname } = useLocation();
const {
services: { executionContext, overlays, theme },
services: { executionContext, overlays, theme, i18n },
} = useMlKibana();
/**
@ -77,7 +78,7 @@ export const useActiveRoute = (routesList: MlRoute[]): MlRoute => {
/>
</p>
</EuiCallOut>,
{ theme$: theme.theme$ }
{ theme, i18n }
)
);
@ -89,7 +90,7 @@ export const useActiveRoute = (routesList: MlRoute[]): MlRoute => {
}, 15000);
}
},
[activeRoute, overlays, theme, pathname]
[activeRoute, overlays, theme, pathname, i18n]
);
useExecutionContext(executionContext, {

View file

@ -7,7 +7,7 @@
import React from 'react';
import type { CoreStart } from '@kbn/core/public';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { extractInfluencers } from '../../../common/util/job_utils';
import { VIEW_BY_JOB_LABEL } from '../../application/explorer/explorer_constants';
import { getDefaultExplorerChartsPanelTitle } from './anomaly_charts_embeddable';
@ -21,7 +21,7 @@ export async function resolveEmbeddableAnomalyChartsUserInput(
coreStart: CoreStart,
input?: AnomalyChartsEmbeddableInput
): Promise<Partial<AnomalyChartsEmbeddableInput>> {
const { http, overlays } = coreStart;
const { http, overlays, theme, i18n } = coreStart;
const { getJobs } = mlApiServicesProvider(new HttpService(http));
@ -32,28 +32,25 @@ export async function resolveEmbeddableAnomalyChartsUserInput(
const { jobs } = await getJobs({ jobId: jobIds.join(',') });
const influencers = extractInfluencers(jobs);
influencers.push(VIEW_BY_JOB_LABEL);
const { theme$ } = coreStart.theme;
const modalSession = overlays.openModal(
toMountPoint(
wrapWithTheme(
<AnomalyChartsInitializer
defaultTitle={title}
initialInput={input}
onCreate={({ panelTitle, maxSeriesToPlot }) => {
modalSession.close();
resolve({
jobIds,
title: panelTitle,
maxSeriesToPlot,
});
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>,
theme$
)
<AnomalyChartsInitializer
defaultTitle={title}
initialInput={input}
onCreate={({ panelTitle, maxSeriesToPlot }) => {
modalSession.close();
resolve({
jobIds,
title: panelTitle,
maxSeriesToPlot,
});
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>,
{ theme, i18n }
)
);
} catch (error) {

View file

@ -7,7 +7,7 @@
import React from 'react';
import type { CoreStart } from '@kbn/core/public';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { extractInfluencers } from '../../../common/util/job_utils';
import { VIEW_BY_JOB_LABEL } from '../../application/explorer/explorer_constants';
import { AnomalySwimlaneInitializer } from './anomaly_swimlane_initializer';
@ -21,7 +21,7 @@ export async function resolveAnomalySwimlaneUserInput(
coreStart: CoreStart,
input?: AnomalySwimlaneEmbeddableInput
): Promise<Partial<AnomalySwimlaneEmbeddableInput>> {
const { http, overlays } = coreStart;
const { http, overlays, theme, i18n } = coreStart;
const { getJobs } = mlApiServicesProvider(new HttpService(http));
@ -32,29 +32,26 @@ export async function resolveAnomalySwimlaneUserInput(
const { jobs } = await getJobs({ jobId: jobIds.join(',') });
const influencers = extractInfluencers(jobs);
influencers.push(VIEW_BY_JOB_LABEL);
const { theme$ } = coreStart.theme;
const modalSession = overlays.openModal(
toMountPoint(
wrapWithTheme(
<AnomalySwimlaneInitializer
defaultTitle={title}
influencers={influencers}
initialInput={input}
onCreate={(explicitInput) => {
modalSession.close();
resolve({
jobIds,
title: explicitInput.panelTitle,
...explicitInput,
});
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>,
theme$
)
<AnomalySwimlaneInitializer
defaultTitle={title}
influencers={influencers}
initialInput={input}
onCreate={(explicitInput) => {
modalSession.close();
resolve({
jobIds,
title: explicitInput.panelTitle,
...explicitInput,
});
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>,
{ theme, i18n }
)
);
} catch (error) {

View file

@ -9,14 +9,11 @@ import moment from 'moment';
import { takeUntil, distinctUntilChanged, skip } from 'rxjs/operators';
import { from } from 'rxjs';
import React from 'react';
import {
KibanaContextProvider,
toMountPoint,
wrapWithTheme,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { getInitialGroupsMap } from '../../application/components/job_selector/job_selector';
import { getMlGlobalServices } from '../../application/app';
import { JobId } from '../../../common/types/anomaly_detection_jobs';
import type { JobId } from '../../../common/types/anomaly_detection_jobs';
import { JobSelectorFlyout } from './components/job_selector_flyout';
/**
@ -35,6 +32,7 @@ export async function resolveJobSelection(
http,
uiSettings,
theme,
i18n,
application: { currentAppId$ },
} = coreStart;
@ -71,23 +69,19 @@ export async function resolveJobSelection(
const flyoutSession = coreStart.overlays.openFlyout(
toMountPoint(
wrapWithTheme(
<KibanaContextProvider
services={{ ...coreStart, mlServices: getMlGlobalServices(http) }}
>
<JobSelectorFlyout
selectedIds={selectedJobIds}
withTimeRangeSelector={false}
dateFormatTz={dateFormatTz}
singleSelection={false}
timeseriesOnly={true}
onFlyoutClose={onFlyoutClose}
onSelectionConfirmed={onSelectionConfirmed}
maps={maps}
/>
</KibanaContextProvider>,
theme.theme$
)
<KibanaContextProvider services={{ ...coreStart, mlServices: getMlGlobalServices(http) }}>
<JobSelectorFlyout
selectedIds={selectedJobIds}
withTimeRangeSelector={false}
dateFormatTz={dateFormatTz}
singleSelection={false}
timeseriesOnly={true}
onFlyoutClose={onFlyoutClose}
onSelectionConfirmed={onSelectionConfirmed}
maps={maps}
/>
</KibanaContextProvider>,
{ theme, i18n }
),
{
'data-test-subj': 'mlFlyoutJobSelector',

View file

@ -8,11 +8,8 @@
import React from 'react';
import { takeUntil, distinctUntilChanged, skip } from 'rxjs/operators';
import { from } from 'rxjs';
import {
toMountPoint,
wrapWithTheme,
KibanaContextProvider,
} from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { CoreStart } from '@kbn/core/public';
@ -34,7 +31,8 @@ export function createFlyout(
): Promise<void> {
const {
http,
theme: { theme$ },
theme,
i18n,
overlays,
application: { currentAppId$ },
} = coreStart;
@ -48,27 +46,25 @@ export function createFlyout(
const flyoutSession = overlays.openFlyout(
toMountPoint(
wrapWithTheme(
<KibanaContextProvider
services={{
...coreStart,
share,
data,
lens,
dashboardService,
mlServices: getMlGlobalServices(http),
<KibanaContextProvider
services={{
...coreStart,
share,
data,
lens,
dashboardService,
mlServices: getMlGlobalServices(http),
}}
>
<FlyoutComponent
embeddable={embeddable}
onClose={() => {
onFlyoutClose();
resolve();
}}
>
<FlyoutComponent
embeddable={embeddable}
onClose={() => {
onFlyoutClose();
resolve();
}}
/>
</KibanaContextProvider>,
theme$
)
/>
</KibanaContextProvider>,
{ theme, i18n }
),
{
'data-test-subj': 'mlFlyoutLayerSelector',

View file

@ -18,7 +18,6 @@ import {
EuiTitle,
EuiSpacer,
EuiText,
useEuiTheme,
} from '@elastic/eui';
import { Layer } from './layer';
@ -32,7 +31,6 @@ interface Props {
}
export const LensLayerSelectionFlyout: FC<Props> = ({ onClose, embeddable }) => {
const { euiTheme } = useEuiTheme();
const {
services: { data, lens },
} = useMlFromLensKibanaContext();
@ -72,7 +70,7 @@ export const LensLayerSelectionFlyout: FC<Props> = ({ onClose, embeddable }) =>
/>
</EuiText>
</EuiFlyoutHeader>
<EuiFlyoutBody css={{ backgroundColor: euiTheme.colors.lightestShade }}>
<EuiFlyoutBody>
{layerResults.map((layer, i) => (
<Layer layer={layer} layerIndex={i} key={layer.id} embeddable={embeddable} />
))}

View file

@ -103,5 +103,6 @@
"@kbn/content-management-plugin",
"@kbn/ml-in-memory-table",
"@kbn/presentation-util-plugin",
"@kbn/react-kibana-mount",
],
}

View file

@ -17,7 +17,6 @@ import { Storage } from '@kbn/kibana-utils-plugin/public';
import { StorageContextProvider } from '@kbn/ml-local-storage';
import { UrlStateProvider } from '@kbn/ml-url-state';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { toMountPoint, wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import type { FieldStatsServices } from '@kbn/unified-field-list/src/components/field_stats';
import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils';
@ -228,9 +227,7 @@ export const Wizard: FC<WizardProps> = React.memo(({ cloneConfig, searchItems })
const stepsConfig = [stepDefine, stepDetails, stepCreate];
const datePickerDeps = {
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings']),
toMountPoint,
wrapWithTheme,
...pick(appDependencies, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']),
uiSettingsKeys: UI_SETTINGS,
};