[8.8] [Visualizations] Fix user profile dark mode bugs (#158162) (#158226)

# 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:
Kibana Machine 2023-05-23 05:07:44 -04:00 committed by GitHub
parent e687aef540
commit adec917694
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 155 additions and 100 deletions

View file

@ -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 };

View file

@ -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);

View file

@ -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);
});
});

View file

@ -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);
});
}

View file

@ -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);

View file

@ -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) {

View file

@ -92,6 +92,7 @@ function wrapSearchBarInContext(testProps: any) {
savedObjects: startMock.savedObjects,
notifications: startMock.notifications,
http: startMock.http,
theme: startMock.theme,
storage: createMockStorage(),
data: {
query: {

View file

@ -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;

View file

@ -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 (

View file

@ -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 {

View file

@ -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 (

View file

@ -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}

View file

@ -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(

View file

@ -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;

View file

@ -148,7 +148,7 @@ export const getDatatableRenderer = (dependencies: {
columnCellValueActions={columnCellValueActions}
columnFilterable={columnsFilterable}
interactive={isInteractive()}
uiSettings={dependencies.uiSettings}
theme={dependencies.theme}
renderComplete={renderComplete}
/>
</I18nProvider>