diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index df364865cd7..3d5257ecd2c 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -53,8 +53,6 @@ "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", "@visx/xychart": "^3.5.1", - "ag-grid-community": "^34.0.2", - "ag-grid-react": "34.0.2", "antd": "^5.24.6", "chrono-node": "^2.7.8", "classnames": "^2.2.5", @@ -60661,6 +60659,8 @@ "@types/json-bigint": "^1.0.4", "@visx/responsive": "^3.12.0", "ace-builds": "^1.43.1", + "ag-grid-community": "^34.0.2", + "ag-grid-react": "34.0.2", "brace": "^0.11.1", "classnames": "^2.2.5", "core-js": "^3.38.1", @@ -62789,8 +62789,6 @@ "@react-icons/all-files": "^4.1.0", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.7.20", - "ag-grid-community": "^34.0.2", - "ag-grid-react": "^34.0.2", "classnames": "^2.5.1", "d3-array": "^2.4.0", "lodash": "^4.17.21", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 2824f94de2d..9006a901465 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -121,8 +121,6 @@ "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", "@visx/xychart": "^3.5.1", - "ag-grid-community": "^34.0.2", - "ag-grid-react": "34.0.2", "antd": "^5.24.6", "chrono-node": "^2.7.8", "classnames": "^2.2.5", diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json index f08cac905f2..4a7fe8c1674 100644 --- a/superset-frontend/packages/superset-ui-core/package.json +++ b/superset-frontend/packages/superset-ui-core/package.json @@ -30,6 +30,8 @@ "@fontsource/inter": "^5.2.6", "@types/json-bigint": "^1.0.4", "ace-builds": "^1.43.1", + "ag-grid-community": "^34.0.2", + "ag-grid-react": "34.0.2", "brace": "^0.11.1", "classnames": "^2.2.5", "csstype": "^3.1.3", diff --git a/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/ThemedAgGridReact.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/ThemedAgGridReact.test.tsx new file mode 100644 index 00000000000..9620659d78d --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/ThemedAgGridReact.test.tsx @@ -0,0 +1,220 @@ +/** + * 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 { render, screen } from '@superset-ui/core/spec'; +import { AgGridReact } from 'ag-grid-react'; +import { createRef } from 'react'; +import { ThemeProvider, supersetTheme } from '../../theme'; +import { ThemedAgGridReact } from './index'; +import * as themeUtils from '../../theme/utils/themeUtils'; + +// Mock useThemeMode hook +jest.mock('../../theme/utils/themeUtils', () => ({ + ...jest.requireActual('../../theme/utils/themeUtils'), + useThemeMode: jest.fn(() => false), // Default to light mode +})); + +// Mock ag-grid-react to avoid complex setup +jest.mock('ag-grid-react', () => ({ + AgGridReact: jest.fn(({ theme, ...props }) => ( +
+ AgGrid Mock +
+ )), +})); + +// Mock ag-grid-community +jest.mock('ag-grid-community', () => ({ + themeQuartz: { + withPart: jest.fn().mockReturnThis(), + withParams: jest.fn(params => ({ ...params, _type: 'theme' })), + }, + colorSchemeDark: { _type: 'dark' }, + colorSchemeLight: { _type: 'light' }, + AllCommunityModule: {}, + ClientSideRowModelModule: {}, + ModuleRegistry: { registerModules: jest.fn() }, +})); + +const mockRowData = [ + { id: 1, name: 'Test 1' }, + { id: 2, name: 'Test 2' }, +]; + +const mockColumnDefs = [ + { field: 'id', headerName: 'ID' }, + { field: 'name', headerName: 'Name' }, +]; + +beforeEach(() => { + jest.clearAllMocks(); + // Reset to light mode by default + (themeUtils.useThemeMode as jest.Mock).mockReturnValue(false); +}); + +test('renders the AgGridReact component', () => { + render( + , + ); + + expect(screen.getByTestId('ag-grid-react')).toBeInTheDocument(); +}); + +test('applies light theme when background is light', () => { + const lightTheme = { + ...supersetTheme, + colorBgBase: '#ffffff', + colorText: '#000000', + }; + + render( + + + , + ); + + const agGrid = screen.getByTestId('ag-grid-react'); + const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}'); + + expect(theme.browserColorScheme).toBe('light'); + expect(theme.foregroundColor).toBe('#000000'); +}); + +test('applies dark theme when background is dark', () => { + // Mock dark mode + (themeUtils.useThemeMode as jest.Mock).mockReturnValue(true); + + const darkTheme = { + ...supersetTheme, + colorBgBase: '#1a1a1a', + colorText: '#ffffff', + }; + + render( + + + , + ); + + const agGrid = screen.getByTestId('ag-grid-react'); + const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}'); + + expect(theme.browserColorScheme).toBe('dark'); + expect(theme.foregroundColor).toBe('#ffffff'); +}); + +test('forwards ref to AgGridReact', () => { + const ref = createRef(); + + render( + , + ); + + // Check that AgGridReact was called with the ref + expect(AgGridReact).toHaveBeenCalledWith( + expect.objectContaining({ + rowData: mockRowData, + columnDefs: mockColumnDefs, + }), + expect.any(Object), // ref is passed as second argument + ); +}); + +test('passes all props through to AgGridReact', () => { + const onGridReady = jest.fn(); + const onCellClicked = jest.fn(); + + render( + , + ); + + expect(AgGridReact).toHaveBeenCalledWith( + expect.objectContaining({ + rowData: mockRowData, + columnDefs: mockColumnDefs, + onGridReady, + onCellClicked, + pagination: true, + paginationPageSize: 10, + }), + expect.any(Object), + ); +}); + +test('applies custom theme colors from Superset theme', () => { + const customTheme = { + ...supersetTheme, + colorFillTertiary: '#e5e5e5', + colorSplit: '#d9d9d9', + }; + + render( + + + , + ); + + const agGrid = screen.getByTestId('ag-grid-react'); + const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}'); + + // Just verify a couple key theme properties are applied + expect(theme.headerBackgroundColor).toBe('#e5e5e5'); + expect(theme.borderColor).toBe('#d9d9d9'); +}); + +test('wraps component with proper container div', () => { + const { container } = render( + , + ); + + const wrapper = container.querySelector('[data-themed-ag-grid="true"]'); + expect(wrapper).toBeInTheDocument(); + // Styles are now applied via css prop, not inline styles + expect(wrapper).toHaveAttribute('data-themed-ag-grid', 'true'); +}); + +test('handles missing theme gracefully', () => { + const incompleteTheme = { + ...supersetTheme, + colorBgBase: undefined, + }; + + render( + + + , + ); + + // Should still render without crashing + expect(screen.getByTestId('ag-grid-react')).toBeInTheDocument(); +}); diff --git a/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/index.tsx new file mode 100644 index 00000000000..5e95a9c0002 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/index.tsx @@ -0,0 +1,190 @@ +/** + * 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 { useMemo, forwardRef } from 'react'; +import { css } from '@emotion/react'; +import { AgGridReact, type AgGridReactProps } from 'ag-grid-react'; +import { + themeQuartz, + colorSchemeDark, + colorSchemeLight, +} from 'ag-grid-community'; +import { useTheme } from '../../theme'; +import { useThemeMode } from '../../theme/utils/themeUtils'; + +// Note: With ag-grid v34's new theming API, CSS files are injected automatically +// Do NOT import 'ag-grid-community/styles/ag-grid.css' or theme CSS files + +export interface ThemedAgGridReactProps extends AgGridReactProps { + /** + * Optional theme parameter overrides to customize specific ag-grid theme values. + * These will be merged with the default Superset theme values. + * + * @example + * ```tsx + * + * ``` + */ + themeOverrides?: Record; +} + +/** + * ThemedAgGridReact - A wrapper around AgGridReact that applies Superset theming + * + * This component: + * - Preserves the full AgGridReactProps interface for drop-in replacement + * - Applies Superset theme variables via ag-grid's JavaScript theming API + * - Supports automatic dark/light mode switching + * - Allows custom theme parameter overrides + * + * @example + * ```tsx + * + * ``` + */ +export const ThemedAgGridReact = forwardRef< + AgGridReact, + ThemedAgGridReactProps +>(function ThemedAgGridReact({ themeOverrides, ...props }, ref) { + const theme = useTheme(); + const isDarkMode = useThemeMode(); + + // Get the appropriate ag-grid theme based on dark/light mode + const agGridTheme = useMemo(() => { + // Use quaternary fill for odd rows + const oddRowBg = theme?.colorFillQuaternary; + + const baseTheme = isDarkMode + ? themeQuartz.withPart(colorSchemeDark) + : themeQuartz.withPart(colorSchemeLight); + + // Use withParams to set colors directly via ag-grid's API + const params = { + // Core colors + backgroundColor: 'transparent', + foregroundColor: theme.colorText, + browserColorScheme: isDarkMode ? 'dark' : 'light', + + // Header styling + headerBackgroundColor: theme.colorFillTertiary, + headerTextColor: theme.colorTextHeading, + + // Cell and row styling + oddRowBackgroundColor: oddRowBg, + rowHoverColor: theme.colorFillSecondary, + selectedRowBackgroundColor: theme.colorPrimaryBg, + cellTextColor: theme.colorText, + + // Borders + borderColor: theme.colorSplit, + columnBorderColor: theme.colorSplit, + + // Interactive elements + accentColor: theme.colorPrimary, + rangeSelectionBorderColor: theme.colorPrimary, + rangeSelectionBackgroundColor: theme.colorPrimaryBg, + + // Input fields (for filters) + inputBackgroundColor: theme.colorBgContainer, + inputBorderColor: theme.colorSplit, + inputTextColor: theme.colorText, + inputPlaceholderTextColor: theme.colorTextPlaceholder, + + // Typography + fontFamily: theme.fontFamily, + fontSize: theme.fontSizeSM, + + // Spacing + spacing: theme.sizeUnit, + }; + + // Only apply params if we have a valid theme + if (!theme || !theme.colorBgBase) { + return baseTheme; + } + + // Merge theme overrides if provided + const finalParams = themeOverrides + ? { ...params, ...themeOverrides } + : params; + + return baseTheme.withParams(finalParams); + }, [theme, isDarkMode, themeOverrides]); + + return ( +
+ +
+ ); +}); + +// Re-export commonly used types for convenience +export type { CustomCellRendererProps } from 'ag-grid-react'; + +// Re-export commonly used ag-grid-community types +export type { + ColDef, + Column, + GridOptions, + GridState, + GridReadyEvent, + CellClickedEvent, + CellClassParams, + IMenuActionParams, + IHeaderParams, + SortModelItem, + ValueFormatterParams, + ValueGetterParams, +} from 'ag-grid-community'; + +// Re-export modules and themes commonly used with ThemedAgGridReact +export { + AllCommunityModule, + ClientSideRowModelModule, + ModuleRegistry, + themeQuartz, + colorSchemeDark, + colorSchemeLight, +} from 'ag-grid-community'; + +// Re-export AgGridReact for ref types +export { AgGridReact } from 'ag-grid-react'; + +// Export the setup function for AG-Grid modules +export { setupAGGridModules } from './setupAGGridModules'; diff --git a/superset-frontend/src/setup/setupAGGridModules.ts b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/setupAGGridModules.ts similarity index 91% rename from superset-frontend/src/setup/setupAGGridModules.ts rename to superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/setupAGGridModules.ts index 63a3d97a4e8..6c0cc641915 100644 --- a/superset-frontend/src/setup/setupAGGridModules.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/ThemedAgGridReact/setupAGGridModules.ts @@ -38,6 +38,10 @@ import { CustomFilterModule, } from 'ag-grid-community'; +/** + * Registers the AG-Grid modules required for Superset's table functionality. + * This should be called once during application initialization. + */ export const setupAGGridModules = () => { ModuleRegistry.registerModules([ ColumnAutoSizeModule, diff --git a/superset-frontend/packages/superset-ui-core/src/components/index.ts b/superset-frontend/packages/superset-ui-core/src/components/index.ts index 578405574c0..e8a69558e67 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/index.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/index.ts @@ -169,3 +169,8 @@ export * from './TelemetryPixel'; export * from './UnsavedChangesModal'; export * from './constants'; export * from './Result'; +export { + ThemedAgGridReact, + type ThemedAgGridReactProps, + setupAGGridModules, +} from './ThemedAgGridReact'; diff --git a/superset-frontend/packages/superset-ui-core/src/theme/utils/themeUtils.ts b/superset-frontend/packages/superset-ui-core/src/theme/utils/themeUtils.ts index f98e2095d8d..36859cc887a 100644 --- a/superset-frontend/packages/superset-ui-core/src/theme/utils/themeUtils.ts +++ b/superset-frontend/packages/superset-ui-core/src/theme/utils/themeUtils.ts @@ -17,6 +17,7 @@ * under the License. */ import tinycolor from 'tinycolor2'; +import { useTheme as useEmotionTheme } from '@emotion/react'; import type { SupersetTheme, FontSizeKey, ColorVariants } from '../types'; const fontSizeMap: Record = { @@ -111,3 +112,12 @@ export function getColorVariants( export function isThemeDark(theme: SupersetTheme): boolean { return tinycolor(theme.colorBgContainer).isDark(); } + +/** + * Hook to determine if the current theme is dark mode + * @returns true if theme is dark, false if light + */ +export function useThemeMode(): boolean { + const theme = useEmotionTheme() as SupersetTheme; + return isThemeDark(theme); +} diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/package.json b/superset-frontend/plugins/plugin-chart-ag-grid-table/package.json index 712477742e5..0771430ecd2 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/package.json +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/package.json @@ -27,8 +27,6 @@ "@react-icons/all-files": "^4.1.0", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.7.20", - "ag-grid-community": "^34.0.2", - "ag-grid-react": "^34.0.2", "classnames": "^2.5.1", "d3-array": "^2.4.0", "lodash": "^4.17.21", diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx index 7804a02f743..c294fb2f06d 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx @@ -27,7 +27,9 @@ import { useEffect, } from 'react'; +import { ThemedAgGridReact } from '@superset-ui/core/components'; import { + AgGridReact, AllCommunityModule, ClientSideRowModelModule, type ColDef, @@ -36,9 +38,7 @@ import { GridState, CellClickedEvent, IMenuActionParams, - themeQuartz, -} from 'ag-grid-community'; -import { AgGridReact } from 'ag-grid-react'; +} from '@superset-ui/core/components/ThemedAgGridReact'; import { type FunctionComponent } from 'react'; import { JsonObject, DataRecordValue, DataRecord, t } from '@superset-ui/core'; import { SearchOutlined } from '@ant-design/icons'; @@ -257,11 +257,7 @@ const AgGridDataTable: FunctionComponent = memo( }; return ( -
+
{renderTimeComparisonDropdown && (
@@ -301,10 +297,9 @@ const AgGridDataTable: FunctionComponent = memo( )}
- string; diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/filterValueGetter.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/filterValueGetter.ts index a6e8a7c75fb..ccdb203a55c 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/filterValueGetter.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/filterValueGetter.ts @@ -17,7 +17,7 @@ * specific language governing permissions and limitations * under the License. */ -import { ValueGetterParams } from 'ag-grid-community'; +import { ValueGetterParams } from '@superset-ui/core/components/ThemedAgGridReact'; const filterValueGetter = (params: ValueGetterParams) => { const raw = params.data[params.colDef.field as string]; diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts index 4b85e3fa9f6..f68e29ec6db 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts @@ -25,7 +25,10 @@ import { isProbablyHTML, sanitizeHtml, } from '@superset-ui/core'; -import { ValueFormatterParams, ValueGetterParams } from 'ag-grid-community'; +import { + ValueFormatterParams, + ValueGetterParams, +} from '@superset-ui/core/components/ThemedAgGridReact'; import { DataColumnMeta, InputColumn } from '../types'; import DateWithFormatter from './DateWithFormatter'; diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellClass.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellClass.ts index 889d8c1225c..fec452ef581 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellClass.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellClass.ts @@ -17,7 +17,7 @@ * under the License. */ -import { CellClassParams } from 'ag-grid-community'; +import { CellClassParams } from '@superset-ui/core/components/ThemedAgGridReact'; import { InputColumn } from '../types'; type GetCellClassParams = CellClassParams & { diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellStyle.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellStyle.ts index 035a3733f39..1aab42b836f 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellStyle.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getCellStyle.ts @@ -18,7 +18,7 @@ */ import { ColorFormatters } from '@superset-ui/chart-controls'; -import { CellClassParams } from 'ag-grid-community'; +import { CellClassParams } from '@superset-ui/core/components/ThemedAgGridReact'; import { BasicColorFormatterType, InputColumn } from '../types'; type CellStyleParams = CellClassParams & { diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getInitialSortState.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getInitialSortState.ts index 8e77d781dd6..54d56b6dba6 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getInitialSortState.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/getInitialSortState.ts @@ -17,7 +17,10 @@ * under the License. */ // All ag grid sort related stuff -import { GridState, SortModelItem } from 'ag-grid-community'; +import { + GridState, + SortModelItem, +} from '@superset-ui/core/components/ThemedAgGridReact'; import { SortByItem } from '../types'; const getInitialSortState = (sortBy?: SortByItem[]): SortModelItem[] => { diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts index 67671aafab4..6de1350fe61 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts @@ -17,7 +17,7 @@ * specific language governing permissions and limitations * under the License. */ -import { ColDef } from 'ag-grid-community'; +import { ColDef } from '@superset-ui/core/components/ThemedAgGridReact'; import { useCallback, useMemo } from 'react'; import { DataRecord, GenericDataType } from '@superset-ui/core'; import { ColorFormatters } from '@superset-ui/chart-controls'; diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useTableTheme.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useTableTheme.ts index 7736fe584a1..629b6439601 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useTableTheme.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useTableTheme.ts @@ -21,7 +21,7 @@ import { colorSchemeDark, colorSchemeLight, themeQuartz, -} from 'ag-grid-community'; +} from '@superset-ui/core/components/ThemedAgGridReact'; // eslint-disable-next-line import/no-extraneous-dependencies import tinycolor from 'tinycolor2'; diff --git a/superset-frontend/src/SqlLab/components/ResultSet/ResultSet.test.tsx b/superset-frontend/src/SqlLab/components/ResultSet/ResultSet.test.tsx index 3c36850b7a9..d4050daf39b 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet/ResultSet.test.tsx +++ b/superset-frontend/src/SqlLab/components/ResultSet/ResultSet.test.tsx @@ -27,7 +27,7 @@ import configureStore from 'redux-mock-store'; import { Store } from 'redux'; import thunk from 'redux-thunk'; import fetchMock from 'fetch-mock'; -import { setupAGGridModules } from 'src/setup/setupAGGridModules'; +import { setupAGGridModules } from '@superset-ui/core/components/ThemedAgGridReact'; import ResultSet from 'src/SqlLab/components/ResultSet'; import { cachedQuery, diff --git a/superset-frontend/src/components/FilterableTable/FilterableTable.test.tsx b/superset-frontend/src/components/FilterableTable/FilterableTable.test.tsx index b5a5ceaeec5..78ec51aef32 100644 --- a/superset-frontend/src/components/FilterableTable/FilterableTable.test.tsx +++ b/superset-frontend/src/components/FilterableTable/FilterableTable.test.tsx @@ -23,7 +23,7 @@ import { userEvent, within, } from 'spec/helpers/testing-library'; -import { setupAGGridModules } from 'src/setup/setupAGGridModules'; +import { setupAGGridModules } from '@superset-ui/core/components/ThemedAgGridReact'; import { FilterableTable } from '.'; describe('FilterableTable', () => { diff --git a/superset-frontend/src/components/GridTable/GridTable.test.tsx b/superset-frontend/src/components/GridTable/GridTable.test.tsx index 09b7b0e699f..75993d4283b 100644 --- a/superset-frontend/src/components/GridTable/GridTable.test.tsx +++ b/superset-frontend/src/components/GridTable/GridTable.test.tsx @@ -17,7 +17,7 @@ * under the License. */ import { render } from 'spec/helpers/testing-library'; -import { setupAGGridModules } from 'src/setup/setupAGGridModules'; +import { setupAGGridModules } from '@superset-ui/core/components/ThemedAgGridReact'; import { GridTable } from '.'; const mockedProps = { diff --git a/superset-frontend/src/components/GridTable/index.tsx b/superset-frontend/src/components/GridTable/index.tsx index df6e1350466..e8b260f28ff 100644 --- a/superset-frontend/src/components/GridTable/index.tsx +++ b/superset-frontend/src/components/GridTable/index.tsx @@ -17,14 +17,10 @@ * under the License. */ import { useCallback, useMemo } from 'react'; -import { Global } from '@emotion/react'; import { css, useTheme } from '@superset-ui/core'; - +import { ThemedAgGridReact } from '@superset-ui/core/components'; import type { Column, GridOptions } from 'ag-grid-community'; -import { AgGridReact, type AgGridReactProps } from 'ag-grid-react'; - -import 'ag-grid-community/styles/ag-grid.css'; -import 'ag-grid-community/styles/ag-theme-quartz.css'; +import type { AgGridReactProps } from 'ag-grid-react'; import copyTextToClipboard from 'src/utils/copy'; @@ -89,7 +85,14 @@ export function GridTable({ { field: PIVOT_COL_ID, valueGetter: 'node.rowIndex+1', - cellClass: 'locked-col', + cellClass: 'row-number-col', + cellStyle: { + backgroundColor: theme.colorFillTertiary, + padding: '0', + textAlign: 'center', + fontSize: '0.9em', + color: theme.colorTextTertiary, + }, width: 30 + rowIndexLength * 6, suppressNavigable: true, resizable: false, @@ -115,7 +118,14 @@ export function GridTable({ }), ), ].slice(showRowNumber ? 0 : 1), - [rowIndexLength, columnReorderable, columns, showRowNumber, sortable], + [ + rowIndexLength, + columnReorderable, + columns, + showRowNumber, + sortable, + theme, + ], ); const defaultColDef: AgGridReactProps['defaultColDef'] = useMemo( () => ({ @@ -142,80 +152,37 @@ export function GridTable({ ); return ( - <> - css` - #grid-table.ag-theme-quartz { - --ag-grid-size: ${theme.sizeUnit}px; - --ag-font-family: ${theme.fontFamily}; - --ag-font-size: ${theme.fontSize}px; - --ag-row-height: ${rowHeight}px; - --ag-background-color: ${theme.colorBgBase}; - --ag-foreground-color: ${theme.colorText}; - --ag-header-background-color: ${theme.colorBgElevated}; - --ag-header-foreground-color: ${theme.colorTextHeading}; - --ag-border-color: ${theme.colorBorder}; - --ag-row-border-color: ${theme.colorSplit}; - --ag-row-hover-color: ${theme.colorFillSecondary}; - --ag-selected-row-background-color: ${theme.colorPrimaryBg}; - --ag-selected-row-foreground-color: ${theme.colorPrimaryText}; - --ag-range-selection-border-color: ${theme.colorPrimary}; - --ag-range-selection-background-color: ${theme.colorPrimaryBg}; - --ag-checkbox-checked-color: ${theme.colorPrimary}; - --ag-disabled-foreground-color: ${theme.colorTextDisabled}; - ${!striped && - `--ag-odd-row-background-color: ${theme.colorBgElevated};`} - --ag-font-size: ${GridSize.Middle === size - ? theme.fontSize - : theme.fontSizeSM}px; - } +
+ -
- -
- +
); } diff --git a/superset-frontend/src/views/App.tsx b/superset-frontend/src/views/App.tsx index 8753014b532..6c18cf76a87 100644 --- a/superset-frontend/src/views/App.tsx +++ b/superset-frontend/src/views/App.tsx @@ -27,13 +27,13 @@ import { import { bindActionCreators } from 'redux'; import { css } from '@superset-ui/core'; import { Layout, Loading } from '@superset-ui/core/components'; +import { setupAGGridModules } from '@superset-ui/core/components/ThemedAgGridReact'; import { ErrorBoundary } from 'src/components'; import Menu from 'src/features/home/Menu'; import getBootstrapData, { applicationRoot } from 'src/utils/getBootstrapData'; import ToastContainer from 'src/components/MessageToasts/ToastContainer'; import setupApp from 'src/setup/setupApp'; import setupPlugins from 'src/setup/setupPlugins'; -import { setupAGGridModules } from 'src/setup/setupAGGridModules'; import { routes, isFrontendRoute } from 'src/views/routes'; import { Logger, LOG_ACTIONS_SPA_NAVIGATION } from 'src/logger/LogUtils'; import setupExtensions from 'src/setup/setupExtensions';