mirror of
https://github.com/apache/superset.git
synced 2026-04-23 18:14:56 +00:00
fix(ag-grid): fix conditional formatting theme colors and module extensibility (#35605)
This commit is contained in:
committed by
GitHub
parent
79918a7939
commit
5e4a80e5d0
@@ -241,10 +241,21 @@ export const getColorFormatters = memoizeOne(
|
||||
(
|
||||
columnConfig: ConditionalFormattingConfig[] | undefined,
|
||||
data: DataRecord[],
|
||||
theme?: Record<string, any>,
|
||||
alpha?: boolean,
|
||||
) =>
|
||||
columnConfig?.reduce(
|
||||
(acc: ColorFormatters, config: ConditionalFormattingConfig) => {
|
||||
let resolvedColorScheme = config.colorScheme;
|
||||
if (
|
||||
theme &&
|
||||
typeof config.colorScheme === 'string' &&
|
||||
config.colorScheme.startsWith('color') &&
|
||||
theme[config.colorScheme]
|
||||
) {
|
||||
resolvedColorScheme = theme[config.colorScheme] as string;
|
||||
}
|
||||
|
||||
if (
|
||||
config?.column !== undefined &&
|
||||
(config?.operator === Comparator.None ||
|
||||
@@ -257,7 +268,7 @@ export const getColorFormatters = memoizeOne(
|
||||
acc.push({
|
||||
column: config?.column,
|
||||
getColorFromValue: getColorFunction(
|
||||
config,
|
||||
{ ...config, colorScheme: resolvedColorScheme },
|
||||
data.map(row => row[config.column!] as number),
|
||||
alpha,
|
||||
),
|
||||
|
||||
@@ -218,3 +218,29 @@ test('handles missing theme gracefully', () => {
|
||||
// Should still render without crashing
|
||||
expect(screen.getByTestId('ag-grid-react')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('merges theme overrides with default theme parameters', () => {
|
||||
const themeOverrides = {
|
||||
fontSize: 16,
|
||||
headerBackgroundColor: '#custom-color',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemedAgGridReact
|
||||
rowData={mockRowData}
|
||||
columnDefs={mockColumnDefs}
|
||||
themeOverrides={themeOverrides}
|
||||
/>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}');
|
||||
|
||||
// Custom overrides should be applied
|
||||
expect(theme.fontSize).toBe(16);
|
||||
expect(theme.headerBackgroundColor).toBe('#custom-color');
|
||||
|
||||
// Default theme parameters should still be present
|
||||
expect(theme.foregroundColor).toBeDefined();
|
||||
expect(theme.borderColor).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -186,5 +186,5 @@ export {
|
||||
// Re-export AgGridReact for ref types
|
||||
export { AgGridReact } from 'ag-grid-react';
|
||||
|
||||
// Export the setup function for AG-Grid modules
|
||||
export { setupAGGridModules } from './setupAGGridModules';
|
||||
// Export the setup function and default modules for AG-Grid
|
||||
export { setupAGGridModules, defaultModules } from './setupAGGridModules';
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ModuleRegistry } from 'ag-grid-community';
|
||||
import { setupAGGridModules, defaultModules } from './setupAGGridModules';
|
||||
|
||||
jest.mock('ag-grid-community', () => ({
|
||||
ModuleRegistry: {
|
||||
registerModules: jest.fn(),
|
||||
},
|
||||
ColumnAutoSizeModule: { moduleName: 'ColumnAutoSizeModule' },
|
||||
ColumnHoverModule: { moduleName: 'ColumnHoverModule' },
|
||||
RowAutoHeightModule: { moduleName: 'RowAutoHeightModule' },
|
||||
RowStyleModule: { moduleName: 'RowStyleModule' },
|
||||
PaginationModule: { moduleName: 'PaginationModule' },
|
||||
CellStyleModule: { moduleName: 'CellStyleModule' },
|
||||
TextFilterModule: { moduleName: 'TextFilterModule' },
|
||||
NumberFilterModule: { moduleName: 'NumberFilterModule' },
|
||||
DateFilterModule: { moduleName: 'DateFilterModule' },
|
||||
ExternalFilterModule: { moduleName: 'ExternalFilterModule' },
|
||||
CsvExportModule: { moduleName: 'CsvExportModule' },
|
||||
ColumnApiModule: { moduleName: 'ColumnApiModule' },
|
||||
RowApiModule: { moduleName: 'RowApiModule' },
|
||||
CellApiModule: { moduleName: 'CellApiModule' },
|
||||
RenderApiModule: { moduleName: 'RenderApiModule' },
|
||||
ClientSideRowModelModule: { moduleName: 'ClientSideRowModelModule' },
|
||||
CustomFilterModule: { moduleName: 'CustomFilterModule' },
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('defaultModules exports an array of AG Grid modules', () => {
|
||||
expect(Array.isArray(defaultModules)).toBe(true);
|
||||
expect(defaultModules.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify it contains expected modules
|
||||
const moduleNames = defaultModules.map((m: any) => m.moduleName);
|
||||
expect(moduleNames).toContain('ColumnAutoSizeModule');
|
||||
expect(moduleNames).toContain('PaginationModule');
|
||||
expect(moduleNames).toContain('ClientSideRowModelModule');
|
||||
});
|
||||
|
||||
test('setupAGGridModules registers default modules when called without arguments', () => {
|
||||
setupAGGridModules();
|
||||
|
||||
expect(ModuleRegistry.registerModules).toHaveBeenCalledTimes(1);
|
||||
expect(ModuleRegistry.registerModules).toHaveBeenCalledWith(defaultModules);
|
||||
});
|
||||
|
||||
test('setupAGGridModules registers default + additional modules when provided', () => {
|
||||
const mockEnterpriseModule1 = { moduleName: 'MultiFilterModule' };
|
||||
const mockEnterpriseModule2 = { moduleName: 'PivotModule' };
|
||||
const additionalModules = [mockEnterpriseModule1, mockEnterpriseModule2];
|
||||
|
||||
setupAGGridModules(additionalModules);
|
||||
|
||||
expect(ModuleRegistry.registerModules).toHaveBeenCalledTimes(1);
|
||||
|
||||
const registeredModules = (ModuleRegistry.registerModules as jest.Mock).mock
|
||||
.calls[0][0];
|
||||
|
||||
// Should contain all default modules
|
||||
defaultModules.forEach(module => {
|
||||
expect(registeredModules).toContain(module);
|
||||
});
|
||||
|
||||
// Should contain additional modules
|
||||
expect(registeredModules).toContain(mockEnterpriseModule1);
|
||||
expect(registeredModules).toContain(mockEnterpriseModule2);
|
||||
|
||||
// Total length should be default + additional
|
||||
expect(registeredModules.length).toBe(
|
||||
defaultModules.length + additionalModules.length,
|
||||
);
|
||||
});
|
||||
|
||||
test('setupAGGridModules handles empty additional modules array', () => {
|
||||
setupAGGridModules([]);
|
||||
|
||||
expect(ModuleRegistry.registerModules).toHaveBeenCalledTimes(1);
|
||||
expect(ModuleRegistry.registerModules).toHaveBeenCalledWith(defaultModules);
|
||||
});
|
||||
|
||||
test('setupAGGridModules does not mutate defaultModules array', () => {
|
||||
const originalLength = defaultModules.length;
|
||||
const mockEnterpriseModule = { moduleName: 'EnterpriseModule' };
|
||||
|
||||
setupAGGridModules([mockEnterpriseModule]);
|
||||
|
||||
// defaultModules should remain unchanged
|
||||
expect(defaultModules.length).toBe(originalLength);
|
||||
expect(defaultModules).not.toContain(mockEnterpriseModule);
|
||||
});
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
import {
|
||||
ModuleRegistry,
|
||||
type Module,
|
||||
ColumnAutoSizeModule,
|
||||
ColumnHoverModule,
|
||||
RowAutoHeightModule,
|
||||
@@ -39,27 +40,29 @@ import {
|
||||
} from 'ag-grid-community';
|
||||
|
||||
/**
|
||||
* Registers the AG-Grid modules required for Superset's table functionality.
|
||||
* This should be called once during application initialization.
|
||||
* Default AG Grid modules that are registered by default.
|
||||
* These modules provide core AG Grid functionality.
|
||||
*/
|
||||
export const setupAGGridModules = () => {
|
||||
ModuleRegistry.registerModules([
|
||||
ColumnAutoSizeModule,
|
||||
ColumnHoverModule,
|
||||
RowAutoHeightModule,
|
||||
RowStyleModule,
|
||||
PaginationModule,
|
||||
CellStyleModule,
|
||||
TextFilterModule,
|
||||
NumberFilterModule,
|
||||
DateFilterModule,
|
||||
ExternalFilterModule,
|
||||
CsvExportModule,
|
||||
ColumnApiModule,
|
||||
RowApiModule,
|
||||
CellApiModule,
|
||||
RenderApiModule,
|
||||
ClientSideRowModelModule,
|
||||
CustomFilterModule,
|
||||
]);
|
||||
export const defaultModules: Module[] = [
|
||||
ColumnAutoSizeModule,
|
||||
ColumnHoverModule,
|
||||
RowAutoHeightModule,
|
||||
RowStyleModule,
|
||||
PaginationModule,
|
||||
CellStyleModule,
|
||||
TextFilterModule,
|
||||
NumberFilterModule,
|
||||
DateFilterModule,
|
||||
ExternalFilterModule,
|
||||
CsvExportModule,
|
||||
ColumnApiModule,
|
||||
RowApiModule,
|
||||
CellApiModule,
|
||||
RenderApiModule,
|
||||
ClientSideRowModelModule,
|
||||
CustomFilterModule,
|
||||
];
|
||||
|
||||
export const setupAGGridModules = (additionalModules: Module[] = []) => {
|
||||
ModuleRegistry.registerModules([...defaultModules, ...additionalModules]);
|
||||
};
|
||||
|
||||
@@ -181,6 +181,7 @@ export {
|
||||
ThemedAgGridReact,
|
||||
type ThemedAgGridReactProps,
|
||||
setupAGGridModules,
|
||||
defaultModules,
|
||||
} from './ThemedAgGridReact';
|
||||
export {
|
||||
CodeEditor,
|
||||
|
||||
Reference in New Issue
Block a user