mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
fix 'Save modal dark theme issues in Discover, Dashboard, and Maps' (#149147)
Fixes https://github.com/elastic/kibana/issues/149130 and https://github.com/elastic/kibana/issues/142636 PR updates `showSaveModal` to wrap modal in `KibanaThemeProvider` to resolve dark theme issues. Rather than passing in theme$ as a new parameter, theme$ is imported from within the plugin itself. Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
ff5101d3c1
commit
d5f6fe84c7
16 changed files with 48 additions and 71 deletions
|
@ -27,7 +27,6 @@ export function runSaveAs(this: DashboardContainer) {
|
|||
timefilter: { timefilter },
|
||||
},
|
||||
},
|
||||
coreContext: { i18nContext },
|
||||
savedObjectsTagging: { hasApi: hasSavedObjectsTagging },
|
||||
dashboardSavedObject: { checkForDuplicateDashboardTitle, saveDashboardStateToSavedObject },
|
||||
} = pluginServices.getServices();
|
||||
|
@ -125,7 +124,7 @@ export function runSaveAs(this: DashboardContainer) {
|
|||
/>
|
||||
);
|
||||
this.clearOverlays();
|
||||
showSaveModal(dashboardSaveModal, i18nContext);
|
||||
showSaveModal(dashboardSaveModal);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ export async function onSaveSearch({
|
|||
onClose={onClose ?? (() => {})}
|
||||
/>
|
||||
);
|
||||
showSaveModal(saveModal, services.core.i18n.Context);
|
||||
showSaveModal(saveModal);
|
||||
}
|
||||
|
||||
const SaveSearchObjectModal: React.FC<{
|
||||
|
|
|
@ -27,8 +27,6 @@ export const mockAttributeService = <
|
|||
const core = customCore ? customCore : coreMock.createStart();
|
||||
return new AttributeService<A, V, R, M>(
|
||||
type,
|
||||
jest.fn(),
|
||||
core.i18n.Context,
|
||||
core.notifications.toasts,
|
||||
options,
|
||||
jest.fn().mockReturnValue(() => ({ getDisplayName: () => type }))
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { get, omit } from 'lodash';
|
||||
import { I18nStart, NotificationsStart } from '@kbn/core/public';
|
||||
import { SavedObjectSaveModal, OnSaveProps, SaveResult } from '@kbn/saved-objects-plugin/public';
|
||||
import { NotificationsStart } from '@kbn/core/public';
|
||||
import {
|
||||
SavedObjectSaveModal,
|
||||
OnSaveProps,
|
||||
SaveResult,
|
||||
showSaveModal,
|
||||
} from '@kbn/saved-objects-plugin/public';
|
||||
import {
|
||||
EmbeddableInput,
|
||||
SavedObjectEmbeddableInput,
|
||||
|
@ -61,11 +66,6 @@ export class AttributeService<
|
|||
> {
|
||||
constructor(
|
||||
private type: string,
|
||||
private showSaveModal: (
|
||||
saveModal: React.ReactElement,
|
||||
I18nContext: I18nStart['Context']
|
||||
) => void,
|
||||
private i18nContext: I18nStart['Context'],
|
||||
private toasts: NotificationsStart['toasts'],
|
||||
private options: AttributeServiceOptions<SavedObjectAttributes, MetaInfo>,
|
||||
getEmbeddableFactory?: (embeddableFactoryId: string) => EmbeddableFactory
|
||||
|
@ -178,7 +178,7 @@ export class AttributeService<
|
|||
}
|
||||
};
|
||||
if (saveOptions && (saveOptions as { showSaveModal: boolean }).showSaveModal) {
|
||||
this.showSaveModal(
|
||||
showSaveModal(
|
||||
<SavedObjectSaveModal
|
||||
onSave={onSave}
|
||||
onClose={() => {}}
|
||||
|
@ -190,8 +190,7 @@ export class AttributeService<
|
|||
showCopyOnSave={false}
|
||||
objectType={this.type}
|
||||
showDescription={false}
|
||||
/>,
|
||||
this.i18nContext
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import React from 'react';
|
|||
import { Subscription } from 'rxjs';
|
||||
import { identity } from 'lodash';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
import { getSavedObjectFinder, showSaveModal } from '@kbn/saved-objects-plugin/public';
|
||||
import { getSavedObjectFinder } from '@kbn/saved-objects-plugin/public';
|
||||
import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||
import { Start as InspectorStart } from '@kbn/inspector-plugin/public';
|
||||
import {
|
||||
|
@ -211,14 +211,7 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
|
|||
getEmbeddableFactory: this.getEmbeddableFactory,
|
||||
getEmbeddableFactories: this.getEmbeddableFactories,
|
||||
getAttributeService: (type: string, options) =>
|
||||
new AttributeService(
|
||||
type,
|
||||
showSaveModal,
|
||||
core.i18n.Context,
|
||||
core.notifications.toasts,
|
||||
options,
|
||||
this.getEmbeddableFactory
|
||||
),
|
||||
new AttributeService(type, core.notifications.toasts, options, this.getEmbeddableFactory),
|
||||
getStateTransfer: (storage?: Storage) =>
|
||||
storage
|
||||
? new EmbeddableStateTransfer(
|
||||
|
|
17
src/plugins/saved_objects/public/kibana_services.ts
Normal file
17
src/plugins/saved_objects/public/kibana_services.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 type { CoreStart } from '@kbn/core/public';
|
||||
|
||||
let coreStart: CoreStart;
|
||||
export function setStartServices(core: CoreStart) {
|
||||
coreStart = core;
|
||||
}
|
||||
|
||||
export const getI18n = () => coreStart.i18n;
|
||||
export const getTheme = () => coreStart.theme;
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from './saved_object';
|
||||
import { PER_PAGE_SETTING, LISTING_LIMIT_SETTING } from '../common';
|
||||
import { SavedObject } from './types';
|
||||
import { setStartServices } from './kibana_services';
|
||||
|
||||
export interface SavedObjectSetup {
|
||||
registerDecorator: (config: SavedObjectDecoratorConfig<any>) => void;
|
||||
|
@ -63,6 +64,7 @@ export class SavedObjectsPublicPlugin
|
|||
};
|
||||
}
|
||||
public start(core: CoreStart, { data, dataViews }: SavedObjectsStartDeps) {
|
||||
setStartServices(core);
|
||||
return {
|
||||
SavedObjectClass: createSavedObjectClass(
|
||||
{
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { I18nStart } from '@kbn/core/public';
|
||||
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { getI18n, getTheme } from '../kibana_services';
|
||||
|
||||
/**
|
||||
* Represents the result of trying to persist the saved object.
|
||||
|
@ -31,7 +32,6 @@ interface MinimalSaveModalProps {
|
|||
|
||||
export function showSaveModal(
|
||||
saveModal: React.ReactElement<MinimalSaveModalProps>,
|
||||
I18nContext: I18nStart['Context'],
|
||||
Wrapper?: React.FC
|
||||
) {
|
||||
const container = document.createElement('div');
|
||||
|
@ -57,13 +57,11 @@ export function showSaveModal(
|
|||
onClose: closeModal,
|
||||
});
|
||||
|
||||
const wrappedElement = Wrapper ? (
|
||||
<I18nContext>
|
||||
<Wrapper>{element}</Wrapper>
|
||||
</I18nContext>
|
||||
) : (
|
||||
<I18nContext>{element}</I18nContext>
|
||||
const I18nContext = getI18n().Context;
|
||||
ReactDOM.render(
|
||||
<KibanaThemeProvider theme$={getTheme().theme$}>
|
||||
<I18nContext>{Wrapper ? <Wrapper>{element}</Wrapper> : element}</I18nContext>
|
||||
</KibanaThemeProvider>,
|
||||
container
|
||||
);
|
||||
|
||||
ReactDOM.render(wrappedElement, container);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import { parse } from 'query-string';
|
|||
|
||||
import { Capabilities } from '@kbn/core/public';
|
||||
import { TopNavMenuData } from '@kbn/navigation-plugin/public';
|
||||
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import {
|
||||
showSaveModal,
|
||||
SavedObjectSaveModalOrigin,
|
||||
|
@ -598,18 +597,7 @@ export const getTopNavConfig = (
|
|||
);
|
||||
}
|
||||
|
||||
const WrapperComponent = ({ children }: { children?: React.ReactNode }) => {
|
||||
const ContextProvider = !originatingApp
|
||||
? presentationUtil.ContextProvider
|
||||
: React.Fragment;
|
||||
return (
|
||||
<KibanaThemeProvider theme$={theme.theme$}>
|
||||
<ContextProvider>{children}</ContextProvider>
|
||||
</KibanaThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
showSaveModal(saveModal, I18nContext, WrapperComponent);
|
||||
showSaveModal(saveModal, presentationUtil.ContextProvider);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
|
@ -10,7 +10,6 @@ import { I18nProvider } from '@kbn/i18n-react';
|
|||
import { Provider } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { showSaveModal } from '@kbn/saved-objects-plugin/public';
|
||||
import { Workspace } from '../types';
|
||||
import { createGraphStore } from '../state_management';
|
||||
import { createWorkspace } from '../services/workspace/graph_client_workspace';
|
||||
|
@ -108,12 +107,10 @@ export const WorkspaceRoute = ({
|
|||
http: coreStart.http,
|
||||
overlays: coreStart.overlays,
|
||||
savedObjectsClient,
|
||||
showSaveModal,
|
||||
savePolicy: graphSavePolicy,
|
||||
changeUrl: (newUrl) => history.push(newUrl),
|
||||
notifyReact: () => setRenderCounter((cur) => cur + 1),
|
||||
chrome,
|
||||
I18nContext: coreStart.i18n.Context,
|
||||
handleSearchQueryError,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { ReactElement } from 'react';
|
||||
import { I18nStart, OverlayStart, SavedObjectsClientContract } from '@kbn/core/public';
|
||||
import React from 'react';
|
||||
import { OverlayStart, SavedObjectsClientContract } from '@kbn/core/public';
|
||||
import { SaveResult } from '@kbn/saved-objects-plugin/public';
|
||||
import { showSaveModal } from '@kbn/saved-objects-plugin/public';
|
||||
import { GraphWorkspaceSavedObject, GraphSavePolicy } from '../types';
|
||||
import { SaveModal, OnSaveGraphProps } from '../components/save_modal';
|
||||
|
||||
|
@ -31,16 +32,12 @@ export function openSaveModal({
|
|||
hasData,
|
||||
workspace,
|
||||
saveWorkspace,
|
||||
showSaveModal,
|
||||
I18nContext,
|
||||
services,
|
||||
}: {
|
||||
savePolicy: GraphSavePolicy;
|
||||
hasData: boolean;
|
||||
workspace: GraphWorkspaceSavedObject;
|
||||
saveWorkspace: SaveWorkspaceHandler;
|
||||
showSaveModal: (el: ReactElement, I18nContext: I18nStart['Context']) => void;
|
||||
I18nContext: I18nStart['Context'];
|
||||
services: SaveWorkspaceServices;
|
||||
}) {
|
||||
const currentTitle = workspace.title;
|
||||
|
@ -79,7 +76,6 @@ export function openSaveModal({
|
|||
title={workspace.title}
|
||||
description={workspace.description}
|
||||
showCopyOnSave={Boolean(workspace.id)}
|
||||
/>,
|
||||
I18nContext
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -66,9 +66,6 @@ export function createMockGraphStore({
|
|||
return { id: '123', title: 'test-pattern' } as unknown as DataView;
|
||||
}),
|
||||
},
|
||||
I18nContext: jest
|
||||
.fn()
|
||||
.mockImplementation(({ children }: { children: React.ReactNode }) => children),
|
||||
notifications: {
|
||||
toasts: {
|
||||
addDanger: jest.fn(),
|
||||
|
@ -78,7 +75,6 @@ export function createMockGraphStore({
|
|||
http: {} as HttpStart,
|
||||
notifyReact: jest.fn(),
|
||||
savePolicy: 'configAndData',
|
||||
showSaveModal: jest.fn(),
|
||||
overlays: {
|
||||
openModal: jest.fn(),
|
||||
} as unknown as OverlayStart,
|
||||
|
|
|
@ -229,9 +229,7 @@ function showModal(
|
|||
savePolicy: deps.savePolicy,
|
||||
hasData: workspace.nodes.length > 0 || workspace.blocklistedNodes.length > 0,
|
||||
workspace: savedWorkspace,
|
||||
showSaveModal: deps.showSaveModal,
|
||||
saveWorkspace: saveWorkspaceHandler,
|
||||
I18nContext: deps.I18nContext,
|
||||
services: {
|
||||
savedObjectsClient: deps.savedObjectsClient,
|
||||
overlays: deps.overlays,
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
import createSagaMiddleware, { SagaMiddleware } from 'redux-saga';
|
||||
import { combineReducers, createStore, Store, AnyAction, Dispatch, applyMiddleware } from 'redux';
|
||||
import { ChromeStart, I18nStart, OverlayStart, SavedObjectsClientContract } from '@kbn/core/public';
|
||||
import { ChromeStart, OverlayStart, SavedObjectsClientContract } from '@kbn/core/public';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { ReactElement } from 'react';
|
||||
import {
|
||||
fieldsReducer,
|
||||
FieldsState,
|
||||
|
@ -48,12 +47,10 @@ export interface GraphStoreDependencies {
|
|||
http: CoreStart['http'];
|
||||
overlays: OverlayStart;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
showSaveModal: (el: ReactElement, I18nContext: I18nStart['Context']) => void;
|
||||
savePolicy: GraphSavePolicy;
|
||||
changeUrl: (newUrl: string) => void;
|
||||
notifyReact: () => void;
|
||||
chrome: ChromeStart;
|
||||
I18nContext: I18nStart['Context'];
|
||||
basePath: string;
|
||||
handleSearchQueryError: (err: Error | string) => void;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ const attributeServiceMockFromSavedVis = (document: Document): LensAttributeServ
|
|||
LensByValueInput,
|
||||
LensByReferenceInput,
|
||||
LensUnwrapMetaInfo
|
||||
>('lens', jest.fn(), core.i18n.Context, core.notifications.toasts, options);
|
||||
>('lens', core.notifications.toasts, options);
|
||||
service.unwrapAttributes = jest.fn((input: LensByValueInput | LensByReferenceInput) => {
|
||||
return Promise.resolve({
|
||||
attributes: {
|
||||
|
|
|
@ -24,7 +24,6 @@ import {
|
|||
getMapsCapabilities,
|
||||
getIsAllowByValueEmbeddables,
|
||||
getInspector,
|
||||
getCoreI18n,
|
||||
getSavedObjectsClient,
|
||||
getCoreOverlays,
|
||||
getSavedObjectsTagging,
|
||||
|
@ -249,7 +248,7 @@ export function getTopNavConfig({
|
|||
);
|
||||
}
|
||||
|
||||
showSaveModal(saveModal, getCoreI18n().Context, PresentationUtilContext);
|
||||
showSaveModal(saveModal, PresentationUtilContext);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue