mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fix theming for error toasts (#160219)
## Summary Fixes https://github.com/elastic/kibana/issues/159153. Applies the current theme (dark/light) to error toasts. Before:  After: 
This commit is contained in:
parent
1a21965403
commit
1223c3f55f
6 changed files with 63 additions and 40 deletions
|
@ -75,7 +75,8 @@ export class NotificationsService {
|
|||
title,
|
||||
error,
|
||||
openModal: overlays.openModal,
|
||||
i18nContext: () => i18nDep.Context,
|
||||
i18n: i18nDep,
|
||||
theme,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import React from 'react';
|
|||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
|
||||
import { ErrorToast } from './error_toast';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks';
|
||||
|
||||
interface ErrorToastProps {
|
||||
error?: Error;
|
||||
|
@ -19,6 +21,8 @@ interface ErrorToastProps {
|
|||
}
|
||||
|
||||
let openModal: jest.Mock;
|
||||
const mockTheme = themeServiceMock.createStartContract();
|
||||
const mockI18n = i18nServiceMock.createStartContract();
|
||||
|
||||
beforeEach(() => (openModal = jest.fn()));
|
||||
|
||||
|
@ -29,9 +33,8 @@ function render(props: ErrorToastProps = {}) {
|
|||
error={props.error || new Error('error message')}
|
||||
title={props.title || 'An error occured'}
|
||||
toastMessage={props.toastMessage || 'This is the toast message'}
|
||||
i18nContext={() =>
|
||||
({ children }) =>
|
||||
<React.Fragment>{children}</React.Fragment>}
|
||||
i18n={mockI18n}
|
||||
theme={mockTheme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,13 +22,16 @@ import { EuiSpacer } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { I18nStart } from '@kbn/core-i18n-browser';
|
||||
import type { OverlayStart } from '@kbn/core-overlays-browser';
|
||||
import { ThemeServiceStart } from '@kbn/core-theme-browser';
|
||||
import { CoreContextProvider } from '@kbn/core-theme-browser-internal';
|
||||
|
||||
interface ErrorToastProps {
|
||||
title: string;
|
||||
error: Error;
|
||||
toastMessage: string;
|
||||
openModal: OverlayStart['openModal'];
|
||||
i18nContext: () => I18nStart['Context'];
|
||||
i18n: I18nStart;
|
||||
theme: ThemeServiceStart;
|
||||
}
|
||||
|
||||
interface RequestError extends Error {
|
||||
|
@ -52,9 +55,9 @@ export function showErrorDialog({
|
|||
title,
|
||||
error,
|
||||
openModal,
|
||||
i18nContext,
|
||||
}: Pick<ErrorToastProps, 'error' | 'title' | 'openModal' | 'i18nContext'>) {
|
||||
const I18nContext = i18nContext();
|
||||
i18n,
|
||||
theme,
|
||||
}: Pick<ErrorToastProps, 'error' | 'title' | 'openModal' | 'i18n' | 'theme'>) {
|
||||
let text = '';
|
||||
|
||||
if (isRequestError(error)) {
|
||||
|
@ -68,32 +71,30 @@ export function showErrorDialog({
|
|||
|
||||
const modal = openModal(
|
||||
mount(
|
||||
<React.Fragment>
|
||||
<I18nContext>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle>{title}</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody data-test-subj="errorModalBody">
|
||||
<EuiCallOut size="s" color="danger" iconType="error" title={error.message} />
|
||||
{text && (
|
||||
<React.Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCodeBlock isCopyable={true} paddingSize="s">
|
||||
{text}
|
||||
</EuiCodeBlock>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</EuiModalBody>
|
||||
<EuiModalFooter>
|
||||
<EuiButton onClick={() => modal.close()} fill>
|
||||
<FormattedMessage
|
||||
id="core.notifications.errorToast.closeModal"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</I18nContext>
|
||||
</React.Fragment>
|
||||
<CoreContextProvider i18n={i18n} theme={theme}>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle>{title}</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody data-test-subj="errorModalBody">
|
||||
<EuiCallOut size="s" color="danger" iconType="error" title={error.message} />
|
||||
{text && (
|
||||
<React.Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCodeBlock isCopyable={true} paddingSize="s">
|
||||
{text}
|
||||
</EuiCodeBlock>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</EuiModalBody>
|
||||
<EuiModalFooter>
|
||||
<EuiButton onClick={() => modal.close()} fill>
|
||||
<FormattedMessage
|
||||
id="core.notifications.errorToast.closeModal"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</CoreContextProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -103,7 +104,8 @@ export function ErrorToast({
|
|||
error,
|
||||
toastMessage,
|
||||
openModal,
|
||||
i18nContext,
|
||||
i18n,
|
||||
theme,
|
||||
}: ErrorToastProps) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
@ -113,7 +115,7 @@ export function ErrorToast({
|
|||
size="s"
|
||||
color="danger"
|
||||
data-test-subj="errorToastBtn"
|
||||
onClick={() => showErrorDialog({ title, error, openModal, i18nContext })}
|
||||
onClick={() => showErrorDialog({ title, error, openModal, i18n, theme })}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="core.toasts.errorToast.seeFullError"
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ToastsApi } from './toasts_api';
|
|||
|
||||
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';
|
||||
import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
|
||||
async function getCurrentToasts(toasts: ToastsApi) {
|
||||
return await firstValueFrom(toasts.get$());
|
||||
|
@ -41,7 +42,11 @@ function toastDeps() {
|
|||
}
|
||||
|
||||
function startDeps() {
|
||||
return { overlays: {} as any, i18n: i18nServiceMock.createStartContract() };
|
||||
return {
|
||||
overlays: {} as any,
|
||||
i18n: i18nServiceMock.createStartContract(),
|
||||
theme: themeServiceMock.createStartContract(),
|
||||
};
|
||||
}
|
||||
|
||||
describe('#get$()', () => {
|
||||
|
|
|
@ -22,6 +22,7 @@ import type {
|
|||
ToastInputFields,
|
||||
ToastOptions,
|
||||
} from '@kbn/core-notifications-browser';
|
||||
import { ThemeServiceStart } from '@kbn/core-theme-browser';
|
||||
import { ErrorToast } from './error_toast';
|
||||
|
||||
const normalizeToast = (toastOrTitle: ToastInput): ToastInputFields => {
|
||||
|
@ -44,15 +45,25 @@ export class ToastsApi implements IToasts {
|
|||
|
||||
private overlays?: OverlayStart;
|
||||
private i18n?: I18nStart;
|
||||
private theme?: ThemeServiceStart;
|
||||
|
||||
constructor(deps: { uiSettings: IUiSettingsClient }) {
|
||||
this.uiSettings = deps.uiSettings;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public start({ overlays, i18n }: { overlays: OverlayStart; i18n: I18nStart }) {
|
||||
public start({
|
||||
overlays,
|
||||
i18n,
|
||||
theme,
|
||||
}: {
|
||||
overlays: OverlayStart;
|
||||
i18n: I18nStart;
|
||||
theme: ThemeServiceStart;
|
||||
}) {
|
||||
this.overlays = overlays;
|
||||
this.i18n = i18n;
|
||||
this.theme = theme;
|
||||
}
|
||||
|
||||
/** Observable of the toast messages to show to the user. */
|
||||
|
@ -176,7 +187,8 @@ export class ToastsApi implements IToasts {
|
|||
error={error}
|
||||
title={options.title}
|
||||
toastMessage={message}
|
||||
i18nContext={() => this.i18n!.Context}
|
||||
i18n={this.i18n!}
|
||||
theme={this.theme!}
|
||||
/>
|
||||
),
|
||||
...options,
|
||||
|
|
|
@ -38,7 +38,7 @@ export class ToastsService {
|
|||
}
|
||||
|
||||
public start({ i18n, overlays, theme, targetDomElement }: StartDeps) {
|
||||
this.api!.start({ overlays, i18n });
|
||||
this.api!.start({ overlays, i18n, theme });
|
||||
this.targetDomElement = targetDomElement;
|
||||
|
||||
render(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue