mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.8`: - [[Visualizations] Fix user profile dark mode bugs (#158162)](https://github.com/elastic/kibana/pull/158162) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Stratoula Kalafateli","email":"efstratia.kalafateli@elastic.co"},"sourceCommit":{"committedDate":"2023-05-23T06:04:43Z","message":"[Visualizations] Fix user profile dark mode bugs (#158162)\n\n## Summary\r\n\r\nCloses https://github.com/elastic/kibana/issues/158154\r\nCloses https://github.com/elastic/kibana/issues/158048\r\nCloses https://github.com/elastic/kibana/issues/158052\r\n\r\nThis PR fixes the UI bugs that were created when we added the user\r\nprofile dark mode settings.\r\n\r\nThere are many cases in our visualizations where we are checking if the\r\nuiSetting is in dark mode and apply custom colors. This is not the case\r\nanymore. Now we need to check this flag from the theme$.\r\n\r\nThere is a bug on the user profile service. When the user profile is set\r\nto Light and the advanced setting is set to dark mode, the dark mode is\r\napplied. I have reported this to the security team.\r\n\r\n### Checklist\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"2c1a2ef93ade7ed28b95293dff735a62f0ff5c70","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Visualizations","Team:Visualizations","release_note:skip","backport:prev-minor","v8.9.0","v8.8.1"],"number":158162,"url":"https://github.com/elastic/kibana/pull/158162","mergeCommit":{"message":"[Visualizations] Fix user profile dark mode bugs (#158162)\n\n## Summary\r\n\r\nCloses https://github.com/elastic/kibana/issues/158154\r\nCloses https://github.com/elastic/kibana/issues/158048\r\nCloses https://github.com/elastic/kibana/issues/158052\r\n\r\nThis PR fixes the UI bugs that were created when we added the user\r\nprofile dark mode settings.\r\n\r\nThere are many cases in our visualizations where we are checking if the\r\nuiSetting is in dark mode and apply custom colors. This is not the case\r\nanymore. Now we need to check this flag from the theme$.\r\n\r\nThere is a bug on the user profile service. When the user profile is set\r\nto Light and the advanced setting is set to dark mode, the dark mode is\r\napplied. I have reported this to the security team.\r\n\r\n### Checklist\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"2c1a2ef93ade7ed28b95293dff735a62f0ff5c70"}},"sourceBranch":"main","suggestedTargetBranches":["8.8"],"targetPullRequestStates":[{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/158162","number":158162,"mergeCommit":{"message":"[Visualizations] Fix user profile dark mode bugs (#158162)\n\n## Summary\r\n\r\nCloses https://github.com/elastic/kibana/issues/158154\r\nCloses https://github.com/elastic/kibana/issues/158048\r\nCloses https://github.com/elastic/kibana/issues/158052\r\n\r\nThis PR fixes the UI bugs that were created when we added the user\r\nprofile dark mode settings.\r\n\r\nThere are many cases in our visualizations where we are checking if the\r\nuiSetting is in dark mode and apply custom colors. This is not the case\r\nanymore. Now we need to check this flag from the theme$.\r\n\r\nThere is a bug on the user profile service. When the user profile is set\r\nto Light and the advanced setting is set to dark mode, the dark mode is\r\napplied. I have reported this to the security team.\r\n\r\n### Checklist\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"2c1a2ef93ade7ed28b95293dff735a62f0ff5c70"}},{"branch":"8.8","label":"v8.8.1","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> --------- Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
parent
e687aef540
commit
adec917694
15 changed files with 155 additions and 100 deletions
|
@ -5,11 +5,12 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { from } from 'rxjs';
|
||||
import { ThemeService } from '@kbn/charts-plugin/public/services';
|
||||
import { uiSettings } from './ui_settings';
|
||||
|
||||
const theme = new ThemeService();
|
||||
theme.init(uiSettings);
|
||||
theme.init({
|
||||
theme$: from([{ darkMode: false }]),
|
||||
});
|
||||
|
||||
export { theme };
|
||||
|
|
|
@ -45,7 +45,7 @@ export class ChartsPlugin implements Plugin<ChartsPluginSetup, ChartsPluginStart
|
|||
public setup(core: CoreSetup, dependencies: SetupDependencies): ChartsPluginSetup {
|
||||
dependencies.expressions.registerFunction(palette);
|
||||
dependencies.expressions.registerFunction(systemPalette);
|
||||
this.themeService.init(core.uiSettings);
|
||||
this.themeService.init(core.theme);
|
||||
this.legacyColorsService.init(core.uiSettings);
|
||||
this.palettes = this.paletteService.setup(this.legacyColorsService);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { from } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { render, act as renderAct } from '@testing-library/react';
|
||||
|
@ -18,7 +18,11 @@ import { EUI_CHARTS_THEME_DARK, EUI_CHARTS_THEME_LIGHT } from '@elastic/eui/dist
|
|||
import { ThemeService } from './theme';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
|
||||
const { uiSettings: setupMockUiSettings } = coreMock.createSetup();
|
||||
const createTheme$Mock = (mode: boolean) => {
|
||||
return from([{ darkMode: mode }]);
|
||||
};
|
||||
|
||||
const { theme: setUpMockTheme } = coreMock.createSetup();
|
||||
|
||||
describe('ThemeService', () => {
|
||||
describe('darkModeEnabled$', () => {
|
||||
|
@ -28,27 +32,30 @@ describe('ThemeService', () => {
|
|||
});
|
||||
|
||||
it('returns the false when not in dark mode', async () => {
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(false));
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
|
||||
expect(await themeService.darkModeEnabled$.pipe(take(1)).toPromise()).toBe(false);
|
||||
expect(await themeService.darkModeEnabled$.pipe(take(1)).toPromise()).toStrictEqual({
|
||||
darkMode: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the true when in dark mode', async () => {
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(true));
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
|
||||
expect(await themeService.darkModeEnabled$.pipe(take(1)).toPromise()).toBe(true);
|
||||
expect(await themeService.darkModeEnabled$.pipe(take(1)).toPromise()).toStrictEqual({
|
||||
darkMode: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('chartsTheme$', () => {
|
||||
it('returns the light theme when not in dark mode', async () => {
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(false));
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
|
||||
expect(await themeService.chartsTheme$.pipe(take(1)).toPromise()).toEqual(
|
||||
EUI_CHARTS_THEME_LIGHT.theme
|
||||
|
@ -58,9 +65,9 @@ describe('ThemeService', () => {
|
|||
describe('in dark mode', () => {
|
||||
it(`returns the dark theme`, async () => {
|
||||
// Fake dark theme turned returning true
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(true));
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
|
||||
expect(await themeService.chartsTheme$.pipe(take(1)).toPromise()).toEqual(
|
||||
EUI_CHARTS_THEME_DARK.theme
|
||||
|
@ -71,9 +78,9 @@ describe('ThemeService', () => {
|
|||
|
||||
describe('chartsBaseTheme$', () => {
|
||||
it('returns the light theme when not in dark mode', async () => {
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(false));
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
|
||||
expect(await themeService.chartsBaseTheme$.pipe(take(1)).toPromise()).toEqual(LIGHT_THEME);
|
||||
});
|
||||
|
@ -81,9 +88,9 @@ describe('ThemeService', () => {
|
|||
describe('in dark mode', () => {
|
||||
it(`returns the dark theme`, async () => {
|
||||
// Fake dark theme turned returning true
|
||||
setupMockUiSettings.get$.mockReturnValue(new BehaviorSubject(true));
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
const result = await themeService.chartsBaseTheme$.pipe(take(1)).toPromise();
|
||||
|
||||
expect(result).toEqual(DARK_THEME);
|
||||
|
@ -92,27 +99,31 @@ describe('ThemeService', () => {
|
|||
});
|
||||
|
||||
describe('useChartsTheme', () => {
|
||||
it('updates when the uiSettings change', () => {
|
||||
const darkMode$ = new BehaviorSubject(false);
|
||||
setupMockUiSettings.get$.mockReturnValue(darkMode$);
|
||||
it('updates when the user profile settings change', () => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
const { useChartsTheme } = themeService;
|
||||
|
||||
const { result } = renderHook(() => useChartsTheme());
|
||||
expect(result.current).toBe(EUI_CHARTS_THEME_LIGHT.theme);
|
||||
|
||||
act(() => darkMode$.next(true));
|
||||
act(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(result.current).toBe(EUI_CHARTS_THEME_DARK.theme);
|
||||
act(() => darkMode$.next(false));
|
||||
act(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(result.current).toBe(EUI_CHARTS_THEME_LIGHT.theme);
|
||||
});
|
||||
|
||||
it('should not rerender when emitting the same value', () => {
|
||||
const darkMode$ = new BehaviorSubject(false);
|
||||
setupMockUiSettings.get$.mockReturnValue(darkMode$);
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
const { useChartsTheme } = themeService;
|
||||
|
||||
const renderCounter = jest.fn();
|
||||
|
@ -124,37 +135,50 @@ describe('ThemeService', () => {
|
|||
|
||||
render(<Wrapper />);
|
||||
expect(renderCounter).toHaveBeenCalledTimes(1);
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(renderCounter).toHaveBeenCalledTimes(2);
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(renderCounter).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useBaseChartTheme', () => {
|
||||
it('updates when the uiSettings change', () => {
|
||||
const darkMode$ = new BehaviorSubject(false);
|
||||
setupMockUiSettings.get$.mockReturnValue(darkMode$);
|
||||
it('updates when the theme setting change', () => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
const { useChartsBaseTheme } = themeService;
|
||||
|
||||
const { result } = renderHook(() => useChartsBaseTheme());
|
||||
expect(result.current).toBe(LIGHT_THEME);
|
||||
|
||||
act(() => darkMode$.next(true));
|
||||
act(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(result.current).toBe(DARK_THEME);
|
||||
act(() => darkMode$.next(false));
|
||||
act(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
// act(() => darkMode$.next(false));
|
||||
expect(result.current).toBe(LIGHT_THEME);
|
||||
});
|
||||
|
||||
it('should not rerender when emitting the same value', () => {
|
||||
const darkMode$ = new BehaviorSubject(false);
|
||||
setupMockUiSettings.get$.mockReturnValue(darkMode$);
|
||||
setUpMockTheme.theme$ = createTheme$Mock(false);
|
||||
const themeService = new ThemeService();
|
||||
themeService.init(setupMockUiSettings);
|
||||
themeService.init(setUpMockTheme);
|
||||
const { useChartsBaseTheme } = themeService;
|
||||
|
||||
const renderCounter = jest.fn();
|
||||
|
@ -166,11 +190,19 @@ describe('ThemeService', () => {
|
|||
|
||||
render(<Wrapper />);
|
||||
expect(renderCounter).toHaveBeenCalledTimes(1);
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(renderCounter).toHaveBeenCalledTimes(2);
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => darkMode$.next(true));
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
renderAct(() => {
|
||||
setUpMockTheme.theme$ = createTheme$Mock(true);
|
||||
themeService.init(setUpMockTheme);
|
||||
});
|
||||
expect(renderCounter).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { CoreSetup } from '@kbn/core/public';
|
||||
import { CoreSetup, CoreTheme } from '@kbn/core/public';
|
||||
import { DARK_THEME, LIGHT_THEME, PartialTheme, Theme } from '@elastic/charts';
|
||||
import { EUI_CHARTS_THEME_DARK, EUI_CHARTS_THEME_LIGHT } from '@elastic/eui/dist/eui_charts_theme';
|
||||
|
||||
|
@ -18,7 +18,7 @@ export class ThemeService {
|
|||
public readonly chartsDefaultTheme = EUI_CHARTS_THEME_LIGHT.theme;
|
||||
public readonly chartsDefaultBaseTheme = LIGHT_THEME;
|
||||
|
||||
private _uiSettingsDarkMode$?: Observable<boolean>;
|
||||
private theme$?: Observable<CoreTheme>;
|
||||
private _chartsTheme$ = new BehaviorSubject(this.chartsDefaultTheme);
|
||||
private _chartsBaseTheme$ = new BehaviorSubject(this.chartsDefaultBaseTheme);
|
||||
|
||||
|
@ -29,12 +29,12 @@ export class ThemeService {
|
|||
public chartsBaseTheme$ = this._chartsBaseTheme$.asObservable();
|
||||
|
||||
/** An observable boolean for dark mode of kibana */
|
||||
public get darkModeEnabled$(): Observable<boolean> {
|
||||
if (!this._uiSettingsDarkMode$) {
|
||||
public get darkModeEnabled$(): Observable<CoreTheme> {
|
||||
if (!this.theme$) {
|
||||
throw new Error('ThemeService not initialized');
|
||||
}
|
||||
|
||||
return this._uiSettingsDarkMode$;
|
||||
return this.theme$;
|
||||
}
|
||||
|
||||
/** A React hook for consuming the dark mode value */
|
||||
|
@ -42,7 +42,9 @@ export class ThemeService {
|
|||
const [value, update] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const s = this.darkModeEnabled$.subscribe(update);
|
||||
const s = this.darkModeEnabled$.subscribe((val) => {
|
||||
update(val.darkMode);
|
||||
});
|
||||
return () => s.unsubscribe();
|
||||
}, []);
|
||||
|
||||
|
@ -86,11 +88,11 @@ export class ThemeService {
|
|||
};
|
||||
|
||||
/** initialize service with uiSettings */
|
||||
public init(uiSettings: CoreSetup['uiSettings']) {
|
||||
this._uiSettingsDarkMode$ = uiSettings.get$<boolean>('theme:darkMode');
|
||||
this._uiSettingsDarkMode$.subscribe((darkMode) => {
|
||||
const theme = darkMode ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme;
|
||||
this._chartsTheme$.next(theme);
|
||||
public init(theme: CoreSetup['theme']) {
|
||||
this.theme$ = theme.theme$;
|
||||
this.theme$.subscribe(({ darkMode }) => {
|
||||
const selectedTheme = darkMode ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme;
|
||||
this._chartsTheme$.next(selectedTheme);
|
||||
this._chartsBaseTheme$.next(darkMode ? DARK_THEME : LIGHT_THEME);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import React, { useRef, memo, useEffect, useState, useCallback } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import classNames from 'classnames';
|
||||
import { SQLLang, monaco } from '@kbn/monaco';
|
||||
import type { AggregateQuery } from '@kbn/es-query';
|
||||
|
@ -108,7 +109,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
const [documentationSections, setDocumentationSections] =
|
||||
useState<LanguageDocumentationSections>();
|
||||
const kibana = useKibana<IUnifiedSearchPluginServices>();
|
||||
const { uiSettings } = kibana.services;
|
||||
const { theme } = kibana.services;
|
||||
|
||||
const styles = textBasedLanguagedEditorStyles(
|
||||
euiTheme,
|
||||
|
@ -118,7 +119,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
Boolean(errors?.length),
|
||||
isCodeEditorExpandedFocused
|
||||
);
|
||||
const isDark = uiSettings.get('theme:darkMode');
|
||||
const isDark: boolean = useObservable(theme.theme$, { darkMode: false }).darkMode;
|
||||
const editorModel = useRef<monaco.editor.ITextModel>();
|
||||
const editor1 = useRef<monaco.editor.IStandaloneCodeEditor>();
|
||||
const containerRef = useRef<HTMLElement>(null);
|
||||
|
|
|
@ -11,17 +11,20 @@ import { act } from 'react-dom/test-utils';
|
|||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { mountWithIntl as mount } from '@kbn/test-jest-helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { TextBasedLanguagesEditor, TextBasedLanguagesEditorProps } from '.';
|
||||
|
||||
describe('TextBasedLanguagesEditor', () => {
|
||||
const uiConfig: Record<string, any> = {};
|
||||
const { theme: setUpMockTheme } = coreMock.createSetup();
|
||||
const uiSettings = {
|
||||
get: (key: string) => uiConfig[key],
|
||||
} as IUiSettingsClient;
|
||||
|
||||
const services = {
|
||||
uiSettings,
|
||||
theme: setUpMockTheme,
|
||||
};
|
||||
|
||||
function renderTextBasedLanguagesEditorComponent(testProps: TextBasedLanguagesEditorProps) {
|
||||
|
|
|
@ -92,6 +92,7 @@ function wrapSearchBarInContext(testProps: any) {
|
|||
savedObjects: startMock.savedObjects,
|
||||
notifications: startMock.notifications,
|
||||
http: startMock.http,
|
||||
theme: startMock.theme,
|
||||
storage: createMockStorage(),
|
||||
data: {
|
||||
query: {
|
||||
|
|
|
@ -87,6 +87,7 @@ export interface IUnifiedSearchPluginServices extends Partial<CoreStart> {
|
|||
notifications: CoreStart['notifications'];
|
||||
application: CoreStart['application'];
|
||||
http: CoreStart['http'];
|
||||
theme: CoreStart['theme'];
|
||||
storage: IStorageWrapper;
|
||||
docLinks: DocLinksStart;
|
||||
data: DataPublicPluginStart;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import React, { useState, useEffect, useMemo, useContext, useCallback, useRef } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { toExpression } from '@kbn/interpreter';
|
||||
|
@ -452,7 +453,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
|
|||
}
|
||||
}, [suggestionForDraggedField, dispatchLens]);
|
||||
|
||||
const IS_DARK_THEME = core.uiSettings.get('theme:darkMode');
|
||||
const IS_DARK_THEME: boolean = useObservable(core.theme.theme$, { darkMode: false }).darkMode;
|
||||
|
||||
const renderDragDropPrompt = () => {
|
||||
return (
|
||||
|
|
|
@ -11,7 +11,7 @@ import { DataContext } from './table_basic';
|
|||
import { createGridCell } from './cell_value';
|
||||
import type { FieldFormat } from '@kbn/field-formats-plugin/common';
|
||||
import { Datatable } from '@kbn/expressions-plugin/public';
|
||||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { DatatableArgs, ColumnConfigArg } from '../../../../common/expressions';
|
||||
|
@ -33,13 +33,14 @@ describe('datatable cell renderer', () => {
|
|||
],
|
||||
rows: [{ a: 123 }],
|
||||
};
|
||||
const { theme: setUpMockTheme } = coreMock.createSetup();
|
||||
const CellRenderer = createGridCell(
|
||||
{
|
||||
a: { convert: (x) => `formatted ${x}` } as FieldFormat,
|
||||
},
|
||||
{ columns: [], sortingColumnId: '', sortingDirection: 'none' },
|
||||
DataContext,
|
||||
{ get: jest.fn() } as unknown as IUiSettingsClient
|
||||
setUpMockTheme
|
||||
);
|
||||
|
||||
it('renders formatted value', () => {
|
||||
|
@ -121,7 +122,7 @@ describe('datatable cell renderer', () => {
|
|||
},
|
||||
{ columns: [], sortingColumnId: '', sortingDirection: 'none' },
|
||||
DataContext,
|
||||
{ get: jest.fn() } as unknown as IUiSettingsClient,
|
||||
setUpMockTheme,
|
||||
true
|
||||
);
|
||||
const cell = mountWithIntl(
|
||||
|
@ -164,7 +165,7 @@ describe('datatable cell renderer', () => {
|
|||
sortingDirection: 'none',
|
||||
},
|
||||
DataContext,
|
||||
{ get: jest.fn() } as unknown as IUiSettingsClient,
|
||||
setUpMockTheme,
|
||||
true
|
||||
);
|
||||
const cell = mountWithIntl(
|
||||
|
@ -202,7 +203,7 @@ describe('datatable cell renderer', () => {
|
|||
},
|
||||
columnConfig,
|
||||
DataContext,
|
||||
{ get: jest.fn() } as unknown as IUiSettingsClient
|
||||
setUpMockTheme
|
||||
);
|
||||
}
|
||||
function getColumnConfiguration(): DatatableArgs {
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
*/
|
||||
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { EuiDataGridCellValueElementProps, EuiLink } from '@elastic/eui';
|
||||
import type { IUiSettingsClient } from '@kbn/core/public';
|
||||
import type { CoreSetup } from '@kbn/core/public';
|
||||
import classNames from 'classnames';
|
||||
import type { FormatFactory } from '../../../../common/types';
|
||||
import { getOriginalId } from '../../../../common/expressions/datatable/transpose_helpers';
|
||||
|
@ -19,14 +20,14 @@ export const createGridCell = (
|
|||
formatters: Record<string, ReturnType<FormatFactory>>,
|
||||
columnConfig: ColumnConfig,
|
||||
DataContext: React.Context<DataContextType>,
|
||||
uiSettings: IUiSettingsClient,
|
||||
theme: CoreSetup['theme'],
|
||||
fitRowToContent?: boolean
|
||||
) => {
|
||||
// Changing theme requires a full reload of the page, so we can cache here
|
||||
const IS_DARK_THEME = uiSettings.get('theme:darkMode');
|
||||
return ({ rowIndex, columnId, setCellProps }: EuiDataGridCellValueElementProps) => {
|
||||
const { table, alignments, minMaxByColumnId, getColorForValue, handleFilterClick } =
|
||||
useContext(DataContext);
|
||||
const IS_DARK_THEME: boolean = useObservable(theme.theme$, { darkMode: false }).darkMode;
|
||||
|
||||
const rowValue = table?.rows[rowIndex]?.[columnId];
|
||||
|
||||
const colIndex = columnConfig.columns.findIndex(({ columnId: id }) => id === columnId);
|
||||
|
@ -69,7 +70,16 @@ export const createGridCell = (
|
|||
});
|
||||
}
|
||||
};
|
||||
}, [rowValue, columnId, setCellProps, colorMode, palette, minMaxByColumnId, getColorForValue]);
|
||||
}, [
|
||||
rowValue,
|
||||
columnId,
|
||||
setCellProps,
|
||||
colorMode,
|
||||
palette,
|
||||
minMaxByColumnId,
|
||||
getColorForValue,
|
||||
IS_DARK_THEME,
|
||||
]);
|
||||
|
||||
if (filterOnClick) {
|
||||
return (
|
||||
|
|
|
@ -15,14 +15,16 @@ import { IFieldFormat, SerializedFieldFormat } from '@kbn/field-formats-plugin/c
|
|||
import { VisualizationContainer } from '../../../visualization_container';
|
||||
import { EmptyPlaceholder } from '@kbn/charts-plugin/public';
|
||||
import { IconChartDatatable } from '@kbn/chart-icons';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { DataContext, DatatableComponent } from './table_basic';
|
||||
import type { DatatableProps } from '../../../../common/expressions';
|
||||
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
|
||||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { Datatable, RenderMode } from '@kbn/expressions-plugin/common';
|
||||
|
||||
import { LENS_EDIT_PAGESIZE_ACTION } from './constants';
|
||||
|
||||
const { theme: setUpMockTheme } = coreMock.createSetup();
|
||||
|
||||
function sampleArgs() {
|
||||
const indexPatternId = 'indexPatternId';
|
||||
const data: Datatable = {
|
||||
|
@ -112,7 +114,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
@ -135,7 +137,7 @@ describe('DatatableComponent', () => {
|
|||
rowHasRowClickTriggerActions={[true, true, true]}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -155,7 +157,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
@ -178,7 +180,7 @@ describe('DatatableComponent', () => {
|
|||
rowHasRowClickTriggerActions={[false, false, false]}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -198,7 +200,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
columnFilterable={[true, true, true]}
|
||||
|
@ -239,7 +241,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
columnFilterable={[true, true, true]}
|
||||
|
@ -315,7 +317,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
columnFilterable={[true, true, true]}
|
||||
|
@ -356,7 +358,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive={false}
|
||||
renderComplete={renderComplete}
|
||||
columnFilterable={[true, true, true]}
|
||||
|
@ -388,7 +390,7 @@ describe('DatatableComponent', () => {
|
|||
)}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -413,7 +415,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -465,7 +467,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -497,7 +499,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -527,7 +529,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -574,7 +576,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -602,7 +604,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="edit"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -641,7 +643,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -678,7 +680,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -715,7 +717,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -751,7 +753,7 @@ describe('DatatableComponent', () => {
|
|||
getType={jest.fn()}
|
||||
renderMode="view"
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
|
@ -776,7 +778,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
@ -814,7 +816,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
@ -863,7 +865,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
@ -889,7 +891,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent: onDispatchEvent,
|
||||
getType: jest.fn(),
|
||||
paletteService: chartPluginMock.createPaletteRegistry(),
|
||||
uiSettings: { get: jest.fn() } as unknown as IUiSettingsClient,
|
||||
theme: setUpMockTheme,
|
||||
renderMode: 'edit' as RenderMode,
|
||||
interactive: true,
|
||||
renderComplete,
|
||||
|
@ -926,7 +928,7 @@ describe('DatatableComponent', () => {
|
|||
dispatchEvent={onDispatchEvent}
|
||||
getType={jest.fn()}
|
||||
paletteService={chartPluginMock.createPaletteRegistry()}
|
||||
uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient}
|
||||
theme={setUpMockTheme}
|
||||
renderMode="edit"
|
||||
interactive
|
||||
renderComplete={renderComplete}
|
||||
|
|
|
@ -388,10 +388,10 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
|
|||
formatters,
|
||||
columnConfig,
|
||||
DataContext,
|
||||
props.uiSettings,
|
||||
props.theme,
|
||||
props.args.fitRowToContent
|
||||
),
|
||||
[formatters, columnConfig, props.uiSettings, props.args.fitRowToContent]
|
||||
[formatters, columnConfig, props.theme, props.args.fitRowToContent]
|
||||
);
|
||||
|
||||
const columnVisibility = useMemo(
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { CoreSetup } from '@kbn/core/public';
|
||||
import type { PaletteRegistry } from '@kbn/coloring';
|
||||
import { CustomPaletteState } from '@kbn/charts-plugin/public';
|
||||
import type { IAggType } from '@kbn/data-plugin/public';
|
||||
|
@ -53,7 +53,7 @@ export type DatatableRenderProps = DatatableProps & {
|
|||
getType: (name: string) => IAggType | undefined;
|
||||
renderMode: RenderMode;
|
||||
paletteService: PaletteRegistry;
|
||||
uiSettings: IUiSettingsClient;
|
||||
theme: CoreSetup['theme'];
|
||||
interactive: boolean;
|
||||
renderComplete: () => void;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ export const getDatatableRenderer = (dependencies: {
|
|||
columnCellValueActions={columnCellValueActions}
|
||||
columnFilterable={columnsFilterable}
|
||||
interactive={isInteractive()}
|
||||
uiSettings={dependencies.uiSettings}
|
||||
theme={dependencies.theme}
|
||||
renderComplete={renderComplete}
|
||||
/>
|
||||
</I18nProvider>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue