Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dashboard] Added KibanaThemeProvider. #120122

Merged
merged 10 commits into from
Dec 7, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import React from 'react';
import { OverlayStart } from '../../../../../core/public';
import { CoreStart, OverlayStart } from '../../../../../core/public';
import { dashboardCopyToDashboardAction } from '../../dashboard_strings';
import { EmbeddableStateTransfer, IEmbeddable } from '../../services/embeddable';
import { toMountPoint } from '../../services/kibana_react';
Expand Down Expand Up @@ -37,6 +37,7 @@ export class CopyToDashboardAction implements Action<CopyToDashboardActionContex
public order = 1;

constructor(
private theme: CoreStart['theme'],
private overlays: OverlayStart,
private stateTransfer: EmbeddableStateTransfer,
private capabilities: DashboardCopyToCapabilities,
Expand Down Expand Up @@ -79,7 +80,8 @@ export class CopyToDashboardAction implements Action<CopyToDashboardActionContex
capabilities={this.capabilities}
dashboardId={(embeddable.parent as DashboardContainer).getInput().id}
embeddable={embeddable}
/>
/>,
{ theme$: this.theme.theme$ }
),
{
maxWidth: 400,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
theme: coreMock.createStart().theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('Export CSV action', () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down Expand Up @@ -90,7 +91,7 @@ beforeEach(async () => {
});

test('Notification is incompatible with Error Embeddables', async () => {
const action = new LibraryNotificationAction(unlinkAction);
const action = new LibraryNotificationAction(coreStart.theme, unlinkAction);
const errorEmbeddable = new ErrorEmbeddable(
'Wow what an awful error',
{ id: ' 404' },
Expand All @@ -100,19 +101,19 @@ test('Notification is incompatible with Error Embeddables', async () => {
});

test('Notification is shown when embeddable on dashboard has reference type input', async () => {
const action = new LibraryNotificationAction(unlinkAction);
const action = new LibraryNotificationAction(coreStart.theme, unlinkAction);
embeddable.updateInput(await embeddable.getInputAsRefType());
expect(await action.isCompatible({ embeddable })).toBe(true);
});

test('Notification is not shown when embeddable input is by value', async () => {
const action = new LibraryNotificationAction(unlinkAction);
const action = new LibraryNotificationAction(coreStart.theme, unlinkAction);
embeddable.updateInput(await embeddable.getInputAsValueType());
expect(await action.isCompatible({ embeddable })).toBe(false);
});

test('Notification is not shown when view mode is set to view', async () => {
const action = new LibraryNotificationAction(unlinkAction);
const action = new LibraryNotificationAction(coreStart.theme, unlinkAction);
embeddable.updateInput(await embeddable.getInputAsRefType());
embeddable.updateInput({ viewMode: ViewMode.VIEW });
expect(await action.isCompatible({ embeddable })).toBe(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import React from 'react';

import { Action, IncompatibleActionError } from '../../services/ui_actions';
import { reactToUiComponent } from '../../services/kibana_react';
import { CoreStart } from '../../../../../core/public';
import { KibanaThemeProvider, reactToUiComponent } from '../../services/kibana_react';
import {
IEmbeddable,
ViewMode,
Expand All @@ -32,7 +33,7 @@ export class LibraryNotificationAction implements Action<LibraryNotificationActi
public readonly type = ACTION_LIBRARY_NOTIFICATION;
public readonly order = 1;

constructor(private unlinkAction: UnlinkFromLibraryAction) {}
constructor(private theme: CoreStart['theme'], private unlinkAction: UnlinkFromLibraryAction) {}

private displayName = dashboardLibraryNotification.getDisplayName();

Expand All @@ -45,13 +46,15 @@ export class LibraryNotificationAction implements Action<LibraryNotificationActi
}) => {
const { embeddable } = context;
return (
<LibraryNotificationPopover
unlinkAction={this.unlinkAction}
displayName={this.displayName}
context={context}
icon={this.getIconType({ embeddable })}
id={this.id}
/>
<KibanaThemeProvider theme$={this.theme.theme$}>
<LibraryNotificationPopover
unlinkAction={this.unlinkAction}
displayName={this.displayName}
context={context}
icon={this.getIconType({ embeddable })}
id={this.id}
/>
</KibanaThemeProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ describe('LibraryNotificationPopover', () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export async function openReplacePanelFlyout(options: {
savedObjectsFinder={savedObjectFinder}
notifications={notifications}
getEmbeddableFactories={getEmbeddableFactories}
/>
/>,
{ theme$: core.theme.theme$ }
),
{
'data-test-subj': 'dashboardReplacePanel',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
theme: coreStart.theme,
presentationUtil: getStubPluginServices(),
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
44 changes: 23 additions & 21 deletions src/plugins/dashboard/public/application/dashboard_router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { DashboardListing } from './listing';
import { dashboardStateStore } from './state';
import { DashboardApp } from './dashboard_app';
import { DashboardNoMatch } from './listing/dashboard_no_match';
import { KibanaContextProvider } from '../services/kibana_react';
import { KibanaContextProvider, KibanaThemeProvider } from '../services/kibana_react';
import { addHelpMenuToAppChrome, DashboardSessionStorage } from './lib';
import { createDashboardListingFilterUrl } from '../dashboard_constants';
import { createDashboardEditUrl, DashboardConstants } from '../dashboard_constants';
Expand Down Expand Up @@ -226,26 +226,28 @@ export async function mountApp({
<Provider store={dashboardStateStore}>
<KibanaContextProvider services={dashboardServices}>
<presentationUtil.ContextProvider>
<HashRouter>
<Switch>
<Route
path={[
DashboardConstants.CREATE_NEW_DASHBOARD_URL,
`${DashboardConstants.VIEW_DASHBOARD_URL}/:id`,
]}
render={renderDashboard}
/>
<Route
exact
path={DashboardConstants.LANDING_PAGE_PATH}
render={renderListingPage}
/>
<Route exact path="/">
<Redirect to={DashboardConstants.LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Switch>
</HashRouter>
<KibanaThemeProvider theme$={core.theme.theme$}>
<HashRouter>
<Switch>
<Route
path={[
DashboardConstants.CREATE_NEW_DASHBOARD_URL,
`${DashboardConstants.VIEW_DASHBOARD_URL}/:id`,
]}
render={renderDashboard}
/>
<Route
exact
path={DashboardConstants.LANDING_PAGE_PATH}
render={renderListingPage}
/>
<Route exact path="/">
<Redirect to={DashboardConstants.LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Switch>
</HashRouter>
</KibanaThemeProvider>
</presentationUtil.ContextProvider>
</KibanaContextProvider>
</Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const options: DashboardContainerServices = {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
theme: coreMock.createStart().theme,
presentationUtil,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
KibanaContextProvider,
KibanaReactContext,
KibanaReactContextValue,
KibanaThemeProvider,
} from '../../services/kibana_react';
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
import { DashboardAppCapabilities, DashboardContainerInput } from '../../types';
Expand All @@ -60,6 +61,7 @@ export interface DashboardContainerServices {
uiSettings: IUiSettingsClient;
embeddable: EmbeddableStart;
uiActions: UiActionsStart;
theme: CoreStart['theme'];
http: CoreStart['http'];
}

Expand Down Expand Up @@ -259,9 +261,11 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
ReactDOM.render(
<I18nProvider>
<KibanaContextProvider services={this.services}>
<this.services.presentationUtil.ContextProvider>
<DashboardViewport container={this} controlGroup={this.controlGroup} />
</this.services.presentationUtil.ContextProvider>
<KibanaThemeProvider theme$={this.services.theme.theme$}>
<this.services.presentationUtil.ContextProvider>
<DashboardViewport container={this} controlGroup={this.controlGroup} />
</this.services.presentationUtil.ContextProvider>
</KibanaThemeProvider>
</KibanaContextProvider>
</I18nProvider>,
dom
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function prepare(props?: Partial<DashboardGridProps>) {
} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
theme: coreMock.createStart().theme,
presentationUtil,
screenshotMode: screenshotModePluginMock.createSetupContract(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { EuiLoadingChart } from '@elastic/eui';
import classNames from 'classnames';
import { CoreStart } from 'src/core/public';
import { Embeddable, EmbeddableInput, IContainer } from '../../../services/embeddable';
import { KibanaThemeProvider } from '../../../services/kibana_react';

export const PLACEHOLDER_EMBEDDABLE = 'placeholder';

export interface PlaceholderEmbeddableServices {
theme: CoreStart['theme'];
}

export class PlaceholderEmbeddable extends Embeddable {
public readonly type = PLACEHOLDER_EMBEDDABLE;
private node?: HTMLElement;

constructor(initialInput: EmbeddableInput, parent?: IContainer) {
constructor(
initialInput: EmbeddableInput,
private readonly services: PlaceholderEmbeddableServices,
parent?: IContainer
) {
super(initialInput, {}, parent);
this.input = initialInput;
}
Expand All @@ -30,9 +40,11 @@ export class PlaceholderEmbeddable extends Embeddable {

const classes = classNames('embPanel', 'embPanel-isLoading');
ReactDOM.render(
<div className={classes}>
<EuiLoadingChart size="l" mono />
</div>,
<KibanaThemeProvider theme$={this.services.theme.theme$}>
<div className={classes}>
<EuiLoadingChart size="l" mono />
</div>
</KibanaThemeProvider>,
node
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ import {
EmbeddableInput,
IContainer,
} from '../../../services/embeddable';
import { PlaceholderEmbeddable, PLACEHOLDER_EMBEDDABLE } from './placeholder_embeddable';
import {
PlaceholderEmbeddable,
PlaceholderEmbeddableServices,
PLACEHOLDER_EMBEDDABLE,
} from './placeholder_embeddable';

export class PlaceholderEmbeddableFactory implements EmbeddableFactoryDefinition {
public readonly type = PLACEHOLDER_EMBEDDABLE;

constructor(private readonly getStartServices: () => Promise<PlaceholderEmbeddableServices>) {}

public async isEditable() {
return false;
}
Expand All @@ -27,7 +33,8 @@ export class PlaceholderEmbeddableFactory implements EmbeddableFactoryDefinition
}

public async create(initialInput: EmbeddableInput, parent?: IContainer) {
return new PlaceholderEmbeddable(initialInput, parent);
const services = await this.getStartServices();
return new PlaceholderEmbeddable(initialInput, services, parent);
}

public getDisplayName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function getProps(props?: Partial<DashboardViewportProps>): {
application: applicationServiceMock.createStartContract(),
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
theme: coreMock.createStart().theme,
embeddable: {
getTriggerCompatibleActions: (() => []) as any,
getEmbeddablePanel: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '@elastic/eui';
import React from 'react';

import { OverlayStart } from '../../../../../core/public';
import { CoreStart, OverlayStart } from '../../../../../core/public';
import { toMountPoint } from '../../services/kibana_react';
import { createConfirmStrings, discardConfirmStrings } from '../../dashboard_strings';

Expand All @@ -43,6 +43,7 @@ export const confirmDiscardUnsavedChanges = (overlays: OverlayStart, discardCall

export const confirmCreateWithUnsaved = (
overlays: OverlayStart,
theme: CoreStart['theme'],
startBlankCallback: () => void,
contineCallback: () => void
) => {
Expand Down Expand Up @@ -105,7 +106,8 @@ export const confirmCreateWithUnsaved = (
</EuiModalFooter>
</div>
</EuiOutsideClickDetector>
</EuiFocusTrap>
</EuiFocusTrap>,
{ theme$: theme.theme$ }
),
{
'data-test-subj': 'dashboardCreateConfirmModal',
Expand Down
Loading