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

## Summary

Closes https://github.com/elastic/kibana/issues/158154
Closes https://github.com/elastic/kibana/issues/158048
Closes https://github.com/elastic/kibana/issues/158052

This PR fixes the UI bugs that were created when we added the user
profile dark mode settings.

There are many cases in our visualizations where we are checking if the
uiSetting is in dark mode and apply custom colors. This is not the case
anymore. Now we need to check this flag from the theme$.

There is a bug on the user profile service. When the user profile is set
to Light and the advanced setting is set to dark mode, the dark mode is
applied. I have reported this to the security team.

### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Stratoula Kalafateli 2023-05-23 09:04:43 +03:00 committed by GitHub
parent 1ea493a36e
commit 2c1a2ef93a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 148 additions and 98 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

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

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>