mirror of
https://github.com/apache/superset.git
synced 2026-05-06 00:14:21 +00:00
Compare commits
1 Commits
docs/testi
...
big-number
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bce6ca1ae0 |
@@ -63,12 +63,6 @@ const restrictedImportsRules = {
|
||||
name: 'antd',
|
||||
message: 'Please import Ant components from the index of src/components',
|
||||
},
|
||||
'no-superset-theme': {
|
||||
name: '@superset-ui/core',
|
||||
importNames: ['supersetTheme'],
|
||||
message:
|
||||
'Please use the theme directly from the ThemeProvider rather than importing supersetTheme.',
|
||||
},
|
||||
'no-query-string': {
|
||||
name: 'query-string',
|
||||
message: 'Please use the URLSearchParams API instead of query-string.',
|
||||
@@ -278,7 +272,6 @@ module.exports = {
|
||||
paths: [
|
||||
restrictedImportsRules['no-moment'],
|
||||
restrictedImportsRules['no-lodash-memoize'],
|
||||
restrictedImportsRules['no-superset-theme'],
|
||||
],
|
||||
patterns: [],
|
||||
},
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { ThemeProvider, supersetTheme } from '../../..';
|
||||
import MatrixifyGridCell from './MatrixifyGridCell';
|
||||
import { MatrixifyGridCell as MatrixifyGridCellType } from '../../types/matrixify';
|
||||
|
||||
@@ -76,11 +75,8 @@ const defaultProps = {
|
||||
rowHeight: 200,
|
||||
};
|
||||
|
||||
const renderWithTheme = (component: React.ReactElement) =>
|
||||
render(<ThemeProvider theme={supersetTheme}>{component}</ThemeProvider>);
|
||||
|
||||
test('should render the cell with title', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
expect(screen.getByText('Revenue - Q1 2024')).toBeInTheDocument();
|
||||
});
|
||||
@@ -91,15 +87,13 @@ test('should render the cell without title when not provided', () => {
|
||||
title: undefined,
|
||||
};
|
||||
|
||||
renderWithTheme(
|
||||
<MatrixifyGridCell {...defaultProps} cell={cellWithoutTitle} />,
|
||||
);
|
||||
render(<MatrixifyGridCell {...defaultProps} cell={cellWithoutTitle} />);
|
||||
|
||||
expect(screen.queryByText('Revenue - Q1 2024')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render SuperChart with correct props', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
expect(superChart).toBeInTheDocument();
|
||||
@@ -108,7 +102,7 @@ test('should render SuperChart with correct props', () => {
|
||||
});
|
||||
|
||||
test('should calculate chart height correctly with title', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
// StatefulChart uses 100% height within the chart wrapper
|
||||
@@ -121,9 +115,7 @@ test('should calculate chart height correctly without title', () => {
|
||||
title: undefined,
|
||||
};
|
||||
|
||||
renderWithTheme(
|
||||
<MatrixifyGridCell {...defaultProps} cell={cellWithoutTitle} />,
|
||||
);
|
||||
render(<MatrixifyGridCell {...defaultProps} cell={cellWithoutTitle} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
// StatefulChart uses 100% height within the chart wrapper
|
||||
@@ -131,9 +123,7 @@ test('should calculate chart height correctly without title', () => {
|
||||
});
|
||||
|
||||
test('should apply correct styling to container', () => {
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridCell {...defaultProps} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
const cellContainer = container.firstChild as HTMLElement;
|
||||
expect(cellContainer).toHaveStyle({
|
||||
@@ -143,7 +133,7 @@ test('should apply correct styling to container', () => {
|
||||
});
|
||||
|
||||
test('should apply correct styling to title', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} />);
|
||||
|
||||
const title = screen.getByText('Revenue - Q1 2024');
|
||||
expect(title).toHaveStyle({
|
||||
@@ -160,9 +150,7 @@ test('should handle different viz types', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithTheme(
|
||||
<MatrixifyGridCell {...defaultProps} cell={cellWithLineChart} />,
|
||||
);
|
||||
render(<MatrixifyGridCell {...defaultProps} cell={cellWithLineChart} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
expect(superChart).toHaveAttribute('data-viz-type', 'line');
|
||||
@@ -178,16 +166,14 @@ test('should pass through additional formData properties', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithTheme(
|
||||
<MatrixifyGridCell {...defaultProps} cell={cellWithExtraProps} />,
|
||||
);
|
||||
render(<MatrixifyGridCell {...defaultProps} cell={cellWithExtraProps} />);
|
||||
|
||||
// The SuperChart mock would receive these props
|
||||
expect(screen.getByText('SuperChart Mock')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should handle small cell dimensions', () => {
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} rowHeight={80} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} rowHeight={80} />);
|
||||
|
||||
const superChart = screen.getByText('SuperChart Mock');
|
||||
const cellContainer = superChart.parentElement?.parentElement;
|
||||
@@ -205,7 +191,7 @@ test('should handle empty cell data gracefully', () => {
|
||||
title: '',
|
||||
};
|
||||
|
||||
renderWithTheme(<MatrixifyGridCell {...defaultProps} cell={emptyCell} />);
|
||||
render(<MatrixifyGridCell {...defaultProps} cell={emptyCell} />);
|
||||
|
||||
// Should still render but with empty title
|
||||
expect(screen.getByText('SuperChart Mock')).toBeInTheDocument();
|
||||
|
||||
@@ -19,10 +19,8 @@
|
||||
|
||||
import { render } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { ThemeProvider } from '@superset-ui/core';
|
||||
import MatrixifyGridRenderer from './MatrixifyGridRenderer';
|
||||
import { generateMatrixifyGrid } from './MatrixifyGridGenerator';
|
||||
import { supersetTheme } from '../../../theme';
|
||||
|
||||
// Mock the MatrixifyGridGenerator
|
||||
jest.mock('./MatrixifyGridGenerator', () => ({
|
||||
@@ -41,9 +39,6 @@ const mockGenerateMatrixifyGrid = generateMatrixifyGrid as jest.MockedFunction<
|
||||
typeof generateMatrixifyGrid
|
||||
>;
|
||||
|
||||
const renderWithTheme = (component: React.ReactElement) =>
|
||||
render(<ThemeProvider theme={supersetTheme}>{component}</ThemeProvider>);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
@@ -81,9 +76,7 @@ test('should create single group when fitting columns dynamically', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// When fitting dynamically, should have only one column group with all 5 columns
|
||||
// Check for the presence of the grid structure
|
||||
@@ -130,9 +123,7 @@ test('should create multiple groups when not fitting columns dynamically', () =>
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// With 5 columns and charts_per_row=3, should have 2 groups (3+2)
|
||||
// With 2 rows and wrapping, we should see headers repeated
|
||||
@@ -165,9 +156,7 @@ test('should handle exact division of columns', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// With 4 columns and charts_per_row=2, should have exactly 2 groups (2+2)
|
||||
// Check that we have column headers - should be 4 total (2 per group)
|
||||
@@ -193,9 +182,7 @@ test('should handle case where charts_per_row exceeds total columns', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// Should create only one group with all columns
|
||||
const columnHeaders = container.querySelectorAll('.matrixify-col-header');
|
||||
@@ -223,9 +210,7 @@ test('should show headers for each group when wrapping occurs', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// With wrapping (multiple column groups), headers should appear for each group
|
||||
const columnHeaders = container.querySelectorAll('.matrixify-col-header');
|
||||
@@ -256,9 +241,7 @@ test('should show headers only on first row when not wrapping', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// Without wrapping, headers should appear only once (first row)
|
||||
const columnHeaders = container.querySelectorAll('.matrixify-col-header');
|
||||
@@ -284,9 +267,7 @@ test('should hide headers when disabled', () => {
|
||||
matrixify_show_column_headers: false,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
const columnHeaders = container.querySelectorAll('.matrixify-col-header');
|
||||
expect(columnHeaders).toHaveLength(0);
|
||||
@@ -313,9 +294,7 @@ test('should place cells correctly in wrapped layout', () => {
|
||||
matrixify_show_column_headers: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// All cells should be rendered
|
||||
const cells = container.querySelectorAll('[data-testid^="grid-cell-"]');
|
||||
@@ -339,9 +318,7 @@ test('should handle null grid gracefully', () => {
|
||||
matrixify_enabled: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
@@ -360,9 +337,7 @@ test('should handle empty grid gracefully', () => {
|
||||
matrixify_enabled: true,
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// Should render container but no cells
|
||||
expect(container).not.toBeEmptyDOMElement();
|
||||
@@ -385,9 +360,7 @@ test('should use default values for missing configuration', () => {
|
||||
// Missing optional configurations
|
||||
};
|
||||
|
||||
const { container } = renderWithTheme(
|
||||
<MatrixifyGridRenderer formData={formData} />,
|
||||
);
|
||||
const { container } = render(<MatrixifyGridRenderer formData={formData} />);
|
||||
|
||||
// Should still render with defaults
|
||||
expect(container).not.toBeEmptyDOMElement();
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import ChartProps, { ChartPropsConfig } from './models/ChartProps';
|
||||
import ChartProps, {
|
||||
ChartPropsConfig,
|
||||
DEFAULT_THEME,
|
||||
} from './models/ChartProps';
|
||||
|
||||
export { default as ChartClient } from './clients/ChartClient';
|
||||
export { default as ChartMetadata } from './models/ChartMetadata';
|
||||
export { default as ChartPlugin } from './models/ChartPlugin';
|
||||
export { ChartProps };
|
||||
export { ChartProps, DEFAULT_THEME };
|
||||
export type { ChartPropsConfig };
|
||||
|
||||
export { default as createLoadableRenderer } from './components/createLoadableRenderer';
|
||||
|
||||
@@ -34,7 +34,10 @@ import {
|
||||
SetDataMaskHook,
|
||||
} from '../types/Base';
|
||||
import { QueryData, DataRecordFilters } from '..';
|
||||
import { supersetTheme, SupersetTheme } from '../../theme';
|
||||
import { SupersetTheme, Theme } from '../../theme';
|
||||
|
||||
// Singleton default theme - created once, reused
|
||||
export const DEFAULT_THEME = Theme.fromConfig().theme;
|
||||
|
||||
// TODO: more specific typing for these fields of ChartProps
|
||||
type AnnotationData = PlainObject;
|
||||
@@ -102,8 +105,8 @@ export interface ChartPropsConfig {
|
||||
isRefreshing?: boolean;
|
||||
/** chart ref */
|
||||
inputRef?: RefObject<any>;
|
||||
/** Theme object */
|
||||
theme: SupersetTheme;
|
||||
/** Theme object - defaults to singleton theme if not provided */
|
||||
theme?: SupersetTheme;
|
||||
/* legend index */
|
||||
legendIndex?: number;
|
||||
inContextMenu?: boolean;
|
||||
@@ -162,7 +165,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
|
||||
|
||||
constructor(
|
||||
config: ChartPropsConfig & { formData?: FormData } = {
|
||||
theme: supersetTheme,
|
||||
theme: DEFAULT_THEME,
|
||||
},
|
||||
) {
|
||||
const {
|
||||
@@ -185,7 +188,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
|
||||
inputRef,
|
||||
inContextMenu = false,
|
||||
emitCrossFilters = false,
|
||||
theme,
|
||||
theme = DEFAULT_THEME,
|
||||
} = config;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import { styled, supersetTheme } from '@superset-ui/core';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { Input } from '../Input';
|
||||
import { Icons, IconNameType } from '.';
|
||||
import type { IconType } from './types';
|
||||
@@ -28,16 +28,17 @@ export default {
|
||||
component: BaseIconComponent,
|
||||
};
|
||||
|
||||
const palette: Record<string, string | null> = {
|
||||
// Icon style options for Storybook controls
|
||||
const iconStyleOptions: Record<string, string | null> = {
|
||||
Default: null,
|
||||
Primary: supersetTheme.colorPrimary,
|
||||
Success: supersetTheme.colorSuccess,
|
||||
Warning: supersetTheme.colorWarning,
|
||||
Error: supersetTheme.colorError,
|
||||
Info: supersetTheme.colorInfo,
|
||||
Text: supersetTheme.colorText,
|
||||
'Text Secondary': supersetTheme.colorTextSecondary,
|
||||
Icon: supersetTheme.colorIcon,
|
||||
Primary: 'primary',
|
||||
Success: 'success',
|
||||
Warning: 'warning',
|
||||
Error: 'error',
|
||||
Info: 'info',
|
||||
Text: 'text',
|
||||
'Text Secondary': 'textSecondary',
|
||||
Icon: 'icon',
|
||||
};
|
||||
|
||||
const IconSet = styled.div`
|
||||
@@ -116,7 +117,7 @@ InteractiveIcons.argTypes = {
|
||||
iconColor: {
|
||||
defaultValue: null,
|
||||
control: { type: 'select' },
|
||||
options: palette,
|
||||
options: iconStyleOptions,
|
||||
},
|
||||
theme: {
|
||||
table: {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
import { render, screen, userEvent, within } from '@superset-ui/core/spec';
|
||||
import * as resizeDetector from 'react-resize-detector';
|
||||
import { supersetTheme, hexToRgb } from '@superset-ui/core';
|
||||
// Theme-specific imports removed - testing behavior, not specific colors
|
||||
import MetadataBar, {
|
||||
MIN_NUMBER_ITEMS,
|
||||
MAX_NUMBER_ITEMS,
|
||||
@@ -157,7 +157,7 @@ test('renders underlined text and emits event when clickable', async () => {
|
||||
expect(style.textDecoration).toBe('underline');
|
||||
});
|
||||
|
||||
test('renders clickable items with blue icons when the bar is collapsed', async () => {
|
||||
test('renders clickable items differently from non-clickable items when the bar is collapsed', async () => {
|
||||
await runWithBarCollapsed(async () => {
|
||||
const onClick = jest.fn();
|
||||
const items = [{ ...ITEMS[0], onClick }, ITEMS[1]];
|
||||
@@ -165,10 +165,8 @@ test('renders clickable items with blue icons when the bar is collapsed', async
|
||||
const images = screen.getAllByRole('img');
|
||||
const clickableColor = window.getComputedStyle(images[0]).color;
|
||||
const nonClickableColor = window.getComputedStyle(images[1]).color;
|
||||
expect(clickableColor).toBe(hexToRgb(supersetTheme.colorPrimary));
|
||||
expect(nonClickableColor.replace(/\s+/g, '')).toBe(
|
||||
supersetTheme.colorTextTertiary.replace(/\s+/g, ''),
|
||||
);
|
||||
// Test that clickable and non-clickable items have different colors
|
||||
expect(clickableColor).not.toBe(nonClickableColor);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
import { render, screen } from '@superset-ui/core/spec';
|
||||
import { AgGridReact } from 'ag-grid-react';
|
||||
import { createRef } from 'react';
|
||||
import { ThemeProvider, supersetTheme } from '../../theme';
|
||||
import { ThemeProvider as EmotionThemeProvider } from '@emotion/react';
|
||||
import { DEFAULT_THEME } from '../../chart';
|
||||
import { ThemedAgGridReact } from './index';
|
||||
import * as themeUtils from '../../theme/utils/themeUtils';
|
||||
|
||||
@@ -81,15 +82,15 @@ test('renders the AgGridReact component', () => {
|
||||
|
||||
test('applies light theme when background is light', () => {
|
||||
const lightTheme = {
|
||||
...supersetTheme,
|
||||
...DEFAULT_THEME,
|
||||
colorBgBase: '#ffffff',
|
||||
colorText: '#000000',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<EmotionThemeProvider theme={lightTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
</EmotionThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
@@ -104,15 +105,15 @@ test('applies dark theme when background is dark', () => {
|
||||
(themeUtils.useThemeMode as jest.Mock).mockReturnValue(true);
|
||||
|
||||
const darkTheme = {
|
||||
...supersetTheme,
|
||||
...DEFAULT_THEME,
|
||||
colorBgBase: '#1a1a1a',
|
||||
colorText: '#ffffff',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={darkTheme}>
|
||||
<EmotionThemeProvider theme={darkTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
</EmotionThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
@@ -173,15 +174,15 @@ test('passes all props through to AgGridReact', () => {
|
||||
|
||||
test('applies custom theme colors from Superset theme', () => {
|
||||
const customTheme = {
|
||||
...supersetTheme,
|
||||
...DEFAULT_THEME,
|
||||
colorFillTertiary: '#e5e5e5',
|
||||
colorSplit: '#d9d9d9',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={customTheme}>
|
||||
<EmotionThemeProvider theme={customTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
</EmotionThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
@@ -205,14 +206,14 @@ test('wraps component with proper container div', () => {
|
||||
|
||||
test('handles missing theme gracefully', () => {
|
||||
const incompleteTheme = {
|
||||
...supersetTheme,
|
||||
...DEFAULT_THEME,
|
||||
colorBgBase: undefined,
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={incompleteTheme}>
|
||||
<EmotionThemeProvider theme={incompleteTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
</EmotionThemeProvider>,
|
||||
);
|
||||
|
||||
// Should still render without crashing
|
||||
|
||||
@@ -20,13 +20,16 @@ import userEvent from '@testing-library/user-event';
|
||||
import { ReactElement } from 'react';
|
||||
import { render, RenderOptions } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { themeObject } from '@superset-ui/core';
|
||||
import { Theme } from '@superset-ui/core';
|
||||
|
||||
// Define the wrapper component outside
|
||||
// Create proper theme instance for core testing
|
||||
const coreTestTheme = Theme.fromConfig();
|
||||
|
||||
// Define the wrapper component with full SupersetThemeProvider
|
||||
const AllTheProviders = ({ children }: { children: React.ReactNode }) => (
|
||||
<themeObject.SupersetThemeProvider>
|
||||
<coreTestTheme.SupersetThemeProvider>
|
||||
{children}
|
||||
</themeObject.SupersetThemeProvider>
|
||||
</coreTestTheme.SupersetThemeProvider>
|
||||
);
|
||||
|
||||
// Follow the exact pattern from RTL docs
|
||||
|
||||
@@ -35,7 +35,6 @@ export {
|
||||
css,
|
||||
keyframes,
|
||||
jsx,
|
||||
ThemeProvider,
|
||||
CacheProvider as EmotionCacheProvider,
|
||||
withTheme,
|
||||
} from '@emotion/react';
|
||||
@@ -58,22 +57,13 @@ export function useTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
// Note: Use Theme.fromConfig().SupersetThemeProvider for proper theming
|
||||
// EmotionThemeProvider available for advanced cases only
|
||||
export { ThemeProvider as EmotionThemeProvider } from '@emotion/react';
|
||||
|
||||
const styled: CreateStyled = emotionStyled;
|
||||
|
||||
const themeObject: Theme = Theme.fromConfig();
|
||||
|
||||
const { theme } = themeObject;
|
||||
const supersetTheme = theme;
|
||||
|
||||
export {
|
||||
Theme,
|
||||
ThemeAlgorithm,
|
||||
ThemeMode,
|
||||
themeObject,
|
||||
styled,
|
||||
theme,
|
||||
supersetTheme,
|
||||
};
|
||||
export { Theme, ThemeAlgorithm, ThemeMode, styled };
|
||||
|
||||
export type {
|
||||
SupersetTheme,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
import mockConsole, { RestoreConsole } from 'jest-mock-console';
|
||||
import { ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps } from '@superset-ui/core';
|
||||
import { render, screen, waitFor } from '@superset-ui/core/spec';
|
||||
import SuperChartCore from '../../../src/chart/components/SuperChartCore';
|
||||
import {
|
||||
@@ -134,7 +134,6 @@ describe('SuperChartCore', () => {
|
||||
it('uses preTransformProps when specified', async () => {
|
||||
const chartPropsWithPayload = new ChartProps({
|
||||
queriesData: [{ message: 'hulk' }],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
render(
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
getChartControlPanelRegistry,
|
||||
QueryFormData,
|
||||
DatasourceType,
|
||||
supersetTheme,
|
||||
VizType,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
@@ -131,7 +130,6 @@ describe('ChartPlugin', () => {
|
||||
width: 400,
|
||||
height: 400,
|
||||
queriesData: [{}],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
it('defaults to identity function', () => {
|
||||
const plugin = new ChartPlugin({
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { Behavior, ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { Behavior, ChartProps } from '@superset-ui/core';
|
||||
|
||||
const RAW_FORM_DATA = {
|
||||
some_field: 1,
|
||||
@@ -42,7 +42,6 @@ describe('ChartProps', () => {
|
||||
height: 600,
|
||||
formData: RAW_FORM_DATA,
|
||||
queriesData: QUERIES_DATA,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
expect(props).toBeInstanceOf(ChartProps);
|
||||
});
|
||||
@@ -53,7 +52,6 @@ describe('ChartProps', () => {
|
||||
datasource: RAW_DATASOURCE,
|
||||
formData: RAW_FORM_DATA,
|
||||
queriesData: QUERIES_DATA,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
expect(props.formData.someField as number).toEqual(1);
|
||||
expect(props.datasource.columnFormats).toEqual(
|
||||
@@ -77,7 +75,6 @@ describe('ChartProps', () => {
|
||||
queriesData: QUERIES_DATA,
|
||||
behaviors: BEHAVIORS,
|
||||
isRefreshing: false,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const props2 = selector({
|
||||
width: 800,
|
||||
@@ -87,7 +84,6 @@ describe('ChartProps', () => {
|
||||
queriesData: QUERIES_DATA,
|
||||
behaviors: BEHAVIORS,
|
||||
isRefreshing: false,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
expect(props1).toBe(props2);
|
||||
});
|
||||
@@ -105,7 +101,6 @@ describe('ChartProps', () => {
|
||||
queriesData: QUERIES_DATA,
|
||||
behaviors: BEHAVIORS,
|
||||
isRefreshing: false,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const props2 = selector({
|
||||
width: 800,
|
||||
@@ -115,7 +110,6 @@ describe('ChartProps', () => {
|
||||
queriesData: QUERIES_DATA,
|
||||
behaviors: BEHAVIORS,
|
||||
isRefreshing: true,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
expect(props1).not.toBe(props2);
|
||||
});
|
||||
@@ -126,7 +120,6 @@ describe('ChartProps', () => {
|
||||
datasource: RAW_DATASOURCE,
|
||||
formData: RAW_FORM_DATA,
|
||||
queriesData: QUERIES_DATA,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const props2 = selector({
|
||||
width: 800,
|
||||
@@ -134,7 +127,6 @@ describe('ChartProps', () => {
|
||||
datasource: RAW_DATASOURCE,
|
||||
formData: { new_field: 3 },
|
||||
queriesData: QUERIES_DATA,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const props3 = selector({
|
||||
width: 800,
|
||||
@@ -142,7 +134,6 @@ describe('ChartProps', () => {
|
||||
datasource: RAW_DATASOURCE,
|
||||
formData: RAW_FORM_DATA,
|
||||
queriesData: QUERIES_DATA,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
expect(props1).not.toBe(props2);
|
||||
expect(props1).toBe(props3);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { SupersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import { Theme } from '@superset-ui/core';
|
||||
|
||||
// CRITICAL: Don't import from the mocked path - import directly to avoid global mocks
|
||||
import AsyncIcon from '../../../src/components/Icons/AsyncIcon';
|
||||
@@ -38,18 +38,15 @@ jest.mock(
|
||||
{ virtual: true },
|
||||
);
|
||||
|
||||
// Basic theme for testing
|
||||
const mockTheme: SupersetTheme = {
|
||||
fontSize: 16,
|
||||
sizeUnit: 4,
|
||||
} as SupersetTheme;
|
||||
// Theme instance for testing
|
||||
const themeInstance = Theme.fromConfig();
|
||||
|
||||
describe('AsyncIcon Integration Tests (Real Component)', () => {
|
||||
it('should have data-test and aria-label attributes with real component', () => {
|
||||
const { container } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<AsyncIcon customIcons fileName="slack" iconSize="l" />
|
||||
</ThemeProvider>,
|
||||
</themeInstance.SupersetThemeProvider>,
|
||||
);
|
||||
|
||||
// Don't wait for SVG since it's mocked - just check the span wrapper
|
||||
@@ -63,9 +60,9 @@ describe('AsyncIcon Integration Tests (Real Component)', () => {
|
||||
|
||||
it('should always have aria-label and data-test for testing', () => {
|
||||
const { container } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<AsyncIcon customIcons fileName="slack" iconSize="l" />
|
||||
</ThemeProvider>,
|
||||
</themeInstance.SupersetThemeProvider>,
|
||||
);
|
||||
|
||||
const spanElement = container.querySelector('span');
|
||||
@@ -84,14 +81,14 @@ describe('AsyncIcon Integration Tests (Real Component)', () => {
|
||||
it('should set role to button when onClick is provided in real component', () => {
|
||||
const onClick = jest.fn();
|
||||
const { container } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<AsyncIcon
|
||||
customIcons
|
||||
fileName="slack"
|
||||
iconSize="l"
|
||||
onClick={onClick}
|
||||
/>
|
||||
</ThemeProvider>,
|
||||
</themeInstance.SupersetThemeProvider>,
|
||||
);
|
||||
|
||||
const spanElement = container.querySelector('span');
|
||||
@@ -107,9 +104,9 @@ describe('AsyncIcon Integration Tests (Real Component)', () => {
|
||||
|
||||
it('should handle complex fileName patterns like BaseIcon', () => {
|
||||
const { container } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<AsyncIcon customIcons fileName="slack_notification" iconSize="l" />
|
||||
</ThemeProvider>,
|
||||
</themeInstance.SupersetThemeProvider>,
|
||||
);
|
||||
|
||||
const spanElement = container.querySelector('span');
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// themeDecorator.js
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import { Theme } from '@superset-ui/core';
|
||||
|
||||
// Create dynamic theme for demo storybook
|
||||
const dynamicTheme = Theme.fromConfig();
|
||||
|
||||
const ThemeDecorator = Story => (
|
||||
<ThemeProvider theme={supersetTheme}>{<Story />}</ThemeProvider>
|
||||
<dynamicTheme.SupersetThemeProvider>{<Story />}</dynamicTheme.SupersetThemeProvider>
|
||||
);
|
||||
|
||||
export default ThemeDecorator;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { supersetTheme, themeObject } from '@superset-ui/core';
|
||||
import { Theme, useTheme } from '@superset-ui/core';
|
||||
|
||||
const colorTypes = [
|
||||
'primary',
|
||||
@@ -66,7 +66,8 @@ const AntDFunctionalColors = () => {
|
||||
<strong>{type}</strong>
|
||||
</td>
|
||||
{variants.map(variant => {
|
||||
const color = themeObject.getColorVariants(type)[variant];
|
||||
const dynamicTheme = Theme.fromConfig();
|
||||
const color = dynamicTheme.getColorVariants(type)[variant];
|
||||
return (
|
||||
<td
|
||||
key={variant}
|
||||
@@ -89,7 +90,8 @@ const AntDFunctionalColors = () => {
|
||||
};
|
||||
|
||||
export const ThemeColors = () => {
|
||||
const { colors } = supersetTheme;
|
||||
const theme = useTheme();
|
||||
const { colors } = theme;
|
||||
|
||||
// Define tones to be displayed in columns
|
||||
const tones = [
|
||||
@@ -154,9 +156,9 @@ export const ThemeColors = () => {
|
||||
<h2>Ant Design Theme Colors</h2>
|
||||
<h3>Functional Colors</h3>
|
||||
<AntDFunctionalColors />
|
||||
<h2>The supersetTheme object</h2>
|
||||
<h2>The Dynamic Theme Object</h2>
|
||||
<pre>
|
||||
<code>{JSON.stringify(supersetTheme, null, 2)}</code>
|
||||
<code>{JSON.stringify(theme, null, 2)}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import { getChartComponentRegistry, ThemeProvider } from '@superset-ui/core';
|
||||
import { getChartComponentRegistry, Theme } from '@superset-ui/core';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { Provider as ReduxProvider } from 'react-redux';
|
||||
import { ChartWrapperProps } from '../types';
|
||||
@@ -31,6 +31,7 @@ export const ChartWrapper: FC<ChartWrapperProps> = ({
|
||||
locale,
|
||||
}) => {
|
||||
const [Chart, setChart] = useState<any>();
|
||||
const themeInstance = Theme.fromConfig();
|
||||
|
||||
const getChartFromRegistry = async (vizType: string) => {
|
||||
const registry = getChartComponentRegistry();
|
||||
@@ -49,7 +50,7 @@ export const ChartWrapper: FC<ChartWrapperProps> = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<ReduxProvider store={mockStore}>
|
||||
{Chart === undefined ? (
|
||||
<></>
|
||||
@@ -57,7 +58,7 @@ export const ChartWrapper: FC<ChartWrapperProps> = ({
|
||||
<Chart {...chartConfig.properties} height={height} width={width} />
|
||||
)}
|
||||
</ReduxProvider>
|
||||
</ThemeProvider>
|
||||
</themeInstance.SupersetThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
ChartProps,
|
||||
getChartTransformPropsRegistry,
|
||||
supersetTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { ChartProps, getChartTransformPropsRegistry } from '@superset-ui/core';
|
||||
|
||||
import { LayerConf, MapViewConfigs, ZoomConfigs } from '../../src/types';
|
||||
import transformProps from '../../src/plugin/transformProps';
|
||||
import {
|
||||
@@ -94,7 +91,6 @@ describe('CartodiagramPlugin transformProps', () => {
|
||||
label_map: groupedTimeseriesLabelMap,
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
let chartTransformPropsPieMock: jest.MockedFunction<any>;
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
*/
|
||||
import {
|
||||
DatasourceType,
|
||||
supersetTheme,
|
||||
TimeGranularity,
|
||||
VizType,
|
||||
DEFAULT_THEME,
|
||||
} from '@superset-ui/core';
|
||||
import transformProps from '../../src/BigNumber/BigNumberWithTrendline/transformProps';
|
||||
import {
|
||||
@@ -99,7 +99,7 @@ function generateProps(
|
||||
ownState: {},
|
||||
filterState: {},
|
||||
behaviors: [],
|
||||
theme: supersetTheme,
|
||||
theme: DEFAULT_THEME,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -219,13 +219,6 @@ describe('BigNumberWithTrendline - Aggregation Tests', () => {
|
||||
},
|
||||
rawDatasource: {},
|
||||
rawFormData: {},
|
||||
theme: {
|
||||
colors: {
|
||||
grayscale: {
|
||||
light5: '#fafafa',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as BigNumberWithTrendlineChartProps;
|
||||
|
||||
const propsWithEvenData = {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, SqlaFormData, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps, SqlaFormData } from '@superset-ui/core';
|
||||
import { EchartsBoxPlotChartProps } from '../../src/BoxPlot/types';
|
||||
import transformProps from '../../src/BoxPlot/transformProps';
|
||||
|
||||
@@ -67,7 +67,6 @@ describe('BoxPlot transformProps', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('should transform chart props for viz', () => {
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
ChartPropsConfig,
|
||||
getNumberFormatter,
|
||||
SqlaFormData,
|
||||
supersetTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { EchartsBubbleChartProps } from 'plugins/plugin-chart-echarts/src/Bubble/types';
|
||||
|
||||
@@ -82,7 +81,6 @@ const chartConfig: ChartPropsConfig = {
|
||||
height: 800,
|
||||
width: 800,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('Bubble transformProps', () => {
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
ChartProps,
|
||||
getNumberFormatter,
|
||||
supersetTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { ChartProps, getNumberFormatter } from '@superset-ui/core';
|
||||
import transformProps, { parseParams } from '../../src/Funnel/transformProps';
|
||||
import {
|
||||
EchartsFunnelChartProps,
|
||||
@@ -47,7 +43,6 @@ const chartProps = new ChartProps({
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
describe('Funnel transformProps', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { AxisType, ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { AxisType, ChartProps } from '@superset-ui/core';
|
||||
import {
|
||||
LegendOrientation,
|
||||
LegendType,
|
||||
@@ -81,7 +81,6 @@ const queriesData = [
|
||||
const chartPropsConfig = {
|
||||
formData,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('Gantt transformProps', () => {
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
CategoricalColorNamespace,
|
||||
ChartProps,
|
||||
SqlaFormData,
|
||||
supersetTheme,
|
||||
VizType,
|
||||
} from '@superset-ui/core';
|
||||
import transformProps, {
|
||||
@@ -71,7 +70,6 @@ describe('Echarts Gauge transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
@@ -121,7 +119,6 @@ describe('Echarts Gauge transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
@@ -182,7 +179,6 @@ describe('Echarts Gauge transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
@@ -246,7 +242,6 @@ describe('Echarts Gauge transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, SqlaFormData, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps, SqlaFormData } from '@superset-ui/core';
|
||||
import transformProps from '../../src/Graph/transformProps';
|
||||
import { DEFAULT_GRAPH_SERIES_OPTION } from '../../src/Graph/constants';
|
||||
import { EchartsGraphChartProps } from '../../src/Graph/types';
|
||||
@@ -53,7 +53,6 @@ const chartPropsConfig = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('EchartsGraph transformProps', () => {
|
||||
@@ -212,7 +211,6 @@ describe('EchartsGraph transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, supersetTheme, VizType } from '@superset-ui/core';
|
||||
import { ChartProps, VizType } from '@superset-ui/core';
|
||||
import {
|
||||
LegendOrientation,
|
||||
LegendType,
|
||||
@@ -114,7 +114,6 @@ const chartPropsConfig = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
it('should transform chart props for viz with showQueryIdentifiers=false', () => {
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
ChartProps,
|
||||
getNumberFormatter,
|
||||
SqlaFormData,
|
||||
supersetTheme,
|
||||
} from '@superset-ui/core';
|
||||
import type { PieSeriesOption } from 'echarts/charts';
|
||||
import type {
|
||||
@@ -56,7 +55,6 @@ describe('Pie transformProps', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('should transform chart props for viz', () => {
|
||||
@@ -152,7 +150,6 @@ describe('Pie label string template', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
}) as EchartsPieChartProps;
|
||||
};
|
||||
|
||||
@@ -253,7 +250,6 @@ describe('Total value positioning with legends', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
}) as EchartsPieChartProps;
|
||||
};
|
||||
|
||||
@@ -426,7 +422,6 @@ describe('Other category', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('generates Other category', () => {
|
||||
@@ -497,7 +492,6 @@ describe('legend sorting', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('sort legend by data', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps } from '@superset-ui/core';
|
||||
import { RadarSeriesOption } from 'echarts/charts';
|
||||
import transformProps from '../../src/Radar/transformProps';
|
||||
import {
|
||||
@@ -88,7 +88,6 @@ const chartProps = new ChartProps({
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
describe('Radar transformProps', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, SqlaFormData, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps, SqlaFormData } from '@superset-ui/core';
|
||||
import { EchartsTimeseriesChartProps } from '../../../src/types';
|
||||
import transformProps from '../../../src/Timeseries/transformProps';
|
||||
import { DEFAULT_FORM_DATA } from '../../../src/Timeseries/constants';
|
||||
@@ -51,7 +51,6 @@ describe('Bar Chart X-axis Time Formatting', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData: timeseriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('Default xAxisTimeFormat', () => {
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
FormulaAnnotationLayer,
|
||||
IntervalAnnotationLayer,
|
||||
SqlaFormData,
|
||||
supersetTheme,
|
||||
TimeseriesAnnotationLayer,
|
||||
} from '@superset-ui/core';
|
||||
import { EchartsTimeseriesChartProps } from '../../src/types';
|
||||
@@ -52,7 +51,6 @@ const chartPropsConfig = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('EchartsTimeseries transformProps', () => {
|
||||
@@ -453,7 +451,6 @@ describe('Does transformProps transform series correctly', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const totalStackedValues = queriesData[0].data.reduce(
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps } from '@superset-ui/core';
|
||||
import transformProps from '../../src/Tree/transformProps';
|
||||
import { EchartsTreeChartProps } from '../../src/Tree/types';
|
||||
|
||||
@@ -35,7 +35,6 @@ describe('EchartsTree transformProps', () => {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
it('should transform when parent present before child', () => {
|
||||
const queriesData = [
|
||||
@@ -189,7 +188,6 @@ describe('EchartsTree transformProps', () => {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
@@ -269,7 +267,6 @@ describe('EchartsTree transformProps', () => {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
@@ -351,7 +348,6 @@ describe('EchartsTree transformProps', () => {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps } from '@superset-ui/core';
|
||||
import { EchartsTreemapChartProps } from '../../src/Treemap/types';
|
||||
import transformProps from '../../src/Treemap/transformProps';
|
||||
|
||||
@@ -40,7 +40,6 @@ describe('Treemap transformProps', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('should transform chart props for viz', () => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ChartProps, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps } from '@superset-ui/core';
|
||||
import {
|
||||
EchartsWaterfallChartProps,
|
||||
WaterfallChartTransformedProps,
|
||||
@@ -59,7 +59,6 @@ describe('Waterfall tranformProps', () => {
|
||||
data,
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const transformedProps = transformProps(
|
||||
chartProps as unknown as EchartsWaterfallChartProps,
|
||||
@@ -82,7 +81,6 @@ describe('Waterfall tranformProps', () => {
|
||||
data,
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const transformedProps = transformProps(
|
||||
chartProps as unknown as EchartsWaterfallChartProps,
|
||||
|
||||
@@ -23,8 +23,9 @@ import {
|
||||
GenericDataType,
|
||||
getNumberFormatter,
|
||||
getTimeFormatter,
|
||||
supersetTheme as theme,
|
||||
DEFAULT_THEME,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import {
|
||||
calculateLowerLogTick,
|
||||
dedupSeries,
|
||||
@@ -51,6 +52,8 @@ import {
|
||||
import { defaultLegendPadding } from '../../src/defaults';
|
||||
import { NULL_STRING } from '../../src/constants';
|
||||
|
||||
const theme = DEFAULT_THEME;
|
||||
|
||||
const expectedThemeProps = {
|
||||
selector: ['all', 'inverse'],
|
||||
selected: undefined,
|
||||
|
||||
@@ -27,10 +27,11 @@ import {
|
||||
EventAnnotationLayer,
|
||||
FormulaAnnotationLayer,
|
||||
IntervalAnnotationLayer,
|
||||
supersetTheme,
|
||||
TimeseriesAnnotationLayer,
|
||||
TimeseriesDataRecord,
|
||||
DEFAULT_THEME,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import { OrientationType } from '../../src';
|
||||
import {
|
||||
transformEventAnnotation,
|
||||
@@ -133,7 +134,7 @@ describe('transformIntervalAnnotation', () => {
|
||||
mockData,
|
||||
mockIntervalAnnotationData,
|
||||
CategoricalColorNamespace.getScale(''),
|
||||
supersetTheme,
|
||||
DEFAULT_THEME,
|
||||
)
|
||||
.map(annotation => annotation.markArea)
|
||||
.map(markArea => markArea.data),
|
||||
@@ -160,7 +161,7 @@ describe('transformIntervalAnnotation', () => {
|
||||
mockData,
|
||||
mockIntervalAnnotationData,
|
||||
CategoricalColorNamespace.getScale(''),
|
||||
supersetTheme,
|
||||
DEFAULT_THEME,
|
||||
undefined,
|
||||
OrientationType.Horizontal,
|
||||
)
|
||||
@@ -224,7 +225,7 @@ describe('transformEventAnnotation', () => {
|
||||
mockData,
|
||||
mockEventAnnotationData,
|
||||
CategoricalColorNamespace.getScale(''),
|
||||
supersetTheme,
|
||||
DEFAULT_THEME,
|
||||
)
|
||||
.map(annotation => annotation.markLine)
|
||||
.map(markLine => markLine.data),
|
||||
@@ -246,7 +247,7 @@ describe('transformEventAnnotation', () => {
|
||||
mockData,
|
||||
mockEventAnnotationData,
|
||||
CategoricalColorNamespace.getScale(''),
|
||||
supersetTheme,
|
||||
DEFAULT_THEME,
|
||||
undefined,
|
||||
OrientationType.Horizontal,
|
||||
)
|
||||
|
||||
@@ -16,12 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
ChartProps,
|
||||
QueryFormData,
|
||||
supersetTheme,
|
||||
VizType,
|
||||
} from '@superset-ui/core';
|
||||
import { ChartProps, QueryFormData, VizType } from '@superset-ui/core';
|
||||
|
||||
import { HandlebarsQueryFormData } from '../../src/types';
|
||||
import transformProps from '../../src/plugin/transformProps';
|
||||
|
||||
@@ -42,7 +38,6 @@ describe('Handlebars transformProps', () => {
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData: [{ data }],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('should transform chart props for viz', () => {
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { ChartProps, QueryFormData, supersetTheme } from '@superset-ui/core';
|
||||
import { ChartProps, QueryFormData } from '@superset-ui/core';
|
||||
|
||||
import transformProps from '../../src/plugin/transformProps';
|
||||
import { MetricsLayoutEnum } from '../../src/types';
|
||||
|
||||
@@ -61,7 +62,6 @@ describe('PivotTableChart transformProps', () => {
|
||||
hooks: { setDataMask },
|
||||
filterState: { selectedFilters: {} },
|
||||
datasource: { verboseMap: {}, columnFormats: {} },
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
it('should transform chart props for viz', () => {
|
||||
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
DatasourceType,
|
||||
GenericDataType,
|
||||
QueryMode,
|
||||
supersetTheme,
|
||||
ComparisonType,
|
||||
VizType,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import { TableChartProps, TableChartFormData } from '../src/types';
|
||||
|
||||
const basicFormData: TableChartFormData = {
|
||||
@@ -67,7 +67,6 @@ const basicChartProps = {
|
||||
},
|
||||
],
|
||||
formData: basicFormData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const basicQueryResult: ChartDataResponseResult = {
|
||||
|
||||
@@ -19,19 +19,22 @@
|
||||
import {
|
||||
EmotionCacheProvider,
|
||||
createEmotionCache,
|
||||
supersetTheme,
|
||||
ThemeProvider,
|
||||
Theme,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
const themeInstance = Theme.fromConfig();
|
||||
|
||||
const emotionCache = createEmotionCache({
|
||||
key: 'test',
|
||||
});
|
||||
|
||||
export function ProviderWrapper(props: any) {
|
||||
const { children, theme = supersetTheme } = props;
|
||||
const { children } = props;
|
||||
return (
|
||||
<EmotionCacheProvider value={emotionCache}>
|
||||
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
{children}
|
||||
</themeInstance.SupersetThemeProvider>
|
||||
</EmotionCacheProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { ThemeProvider } from '@superset-ui/core';
|
||||
import { Theme } from '@superset-ui/core';
|
||||
import { BrowserRouter as Router, Route } from 'react-router-dom';
|
||||
import { QueryParamProvider } from 'use-query-params';
|
||||
|
||||
export function ProviderWrapper(props: any) {
|
||||
const { children, theme } = props;
|
||||
const { children } = props;
|
||||
const themeInstance = Theme.fromConfig();
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<themeInstance.SupersetThemeProvider>
|
||||
<Router>
|
||||
<QueryParamProvider
|
||||
ReactRouterRoute={Route}
|
||||
@@ -34,6 +35,6 @@ export function ProviderWrapper(props: any) {
|
||||
{children}
|
||||
</QueryParamProvider>
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</themeInstance.SupersetThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,12 +26,7 @@ import {
|
||||
waitFor,
|
||||
within,
|
||||
} from '@testing-library/react';
|
||||
import {
|
||||
ThemeProvider,
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
supersetTheme,
|
||||
themeObject,
|
||||
} from '@superset-ui/core';
|
||||
import { Theme } from '@superset-ui/core';
|
||||
import { SupersetThemeProvider } from 'src/theme/ThemeProvider';
|
||||
import { ThemeController } from 'src/theme/ThemeController';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
@@ -56,7 +51,8 @@ type Options = Omit<RenderOptions, 'queries'> & {
|
||||
store?: Store;
|
||||
};
|
||||
|
||||
const themeController = new ThemeController({ themeObject });
|
||||
// Create theme controller for advanced testing scenarios
|
||||
const themeController = new ThemeController();
|
||||
|
||||
export const createStore = (initialState: object = {}, reducers: object = {}) =>
|
||||
configureStore({
|
||||
@@ -85,10 +81,12 @@ export function createWrapper(options?: Options) {
|
||||
} = options || {};
|
||||
|
||||
return ({ children }: { children?: ReactNode }) => {
|
||||
// Create theme instance for this test session
|
||||
const testTheme = Theme.fromConfig();
|
||||
let result = (
|
||||
<ThemeProvider theme={supersetTheme}>
|
||||
<testTheme.SupersetThemeProvider>
|
||||
<ExtensionsProvider>{children}</ExtensionsProvider>
|
||||
</ThemeProvider>
|
||||
</testTheme.SupersetThemeProvider>
|
||||
);
|
||||
|
||||
if (useTheme) {
|
||||
|
||||
@@ -29,8 +29,8 @@ import {
|
||||
FeatureFlag,
|
||||
styled,
|
||||
SupersetClient,
|
||||
themeObject,
|
||||
t,
|
||||
useTheme,
|
||||
withTheme,
|
||||
getClientErrorObject,
|
||||
getExtensionsRegistry,
|
||||
@@ -563,8 +563,9 @@ StackedField.propTypes = {
|
||||
};
|
||||
|
||||
function FormContainer({ children }) {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Card padded style={{ backgroundColor: themeObject.theme.colorBgLayout }}>
|
||||
<Card padded style={{ backgroundColor: theme.colorBgLayout }}>
|
||||
{children}
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import { ErrorLevel, supersetTheme } from '@superset-ui/core';
|
||||
import { ErrorLevel } from '@superset-ui/core';
|
||||
import { BasicErrorAlert } from './BasicErrorAlert';
|
||||
|
||||
jest.mock(
|
||||
@@ -68,24 +68,16 @@ test('should render the error body', () => {
|
||||
expect(screen.getByText('Error body')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render with warning theme', () => {
|
||||
test('should render warning alert', () => {
|
||||
render(<BasicErrorAlert {...mockedProps} />);
|
||||
expect(screen.getByRole('alert')).toHaveStyle(
|
||||
`
|
||||
color: ${supersetTheme.colorWarningText};
|
||||
`,
|
||||
);
|
||||
expect(screen.getByRole('alert')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render with error theme', () => {
|
||||
test('should render error alert', () => {
|
||||
const errorProps = {
|
||||
...mockedProps,
|
||||
level: 'error' as ErrorLevel,
|
||||
};
|
||||
render(<BasicErrorAlert {...errorProps} />);
|
||||
expect(screen.getByRole('alert')).toHaveStyle(
|
||||
`
|
||||
color: ${supersetTheme.colorErrorText};
|
||||
`,
|
||||
);
|
||||
expect(screen.getByRole('alert')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { supersetTheme } from '@superset-ui/core';
|
||||
import { useEffect } from 'react';
|
||||
import { useTheme } from '@superset-ui/core';
|
||||
import {
|
||||
cleanup,
|
||||
render,
|
||||
@@ -163,16 +164,46 @@ function getCheckboxIcon(element: HTMLElement): Element {
|
||||
/**
|
||||
* Unfortunately when using react-checkbox-tree, the only perceived change of a
|
||||
* checkbox state change is the fill color of the SVG icon.
|
||||
*
|
||||
* Helper component to access theme context for state detection.
|
||||
*/
|
||||
function CheckboxStateDetector({
|
||||
name,
|
||||
onStateDetected,
|
||||
}: {
|
||||
name: string;
|
||||
onStateDetected: (state: CheckboxState) => void;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
const element = screen.getByRole('link', { name });
|
||||
const svgPath =
|
||||
getCheckboxIcon(element).children[1].children[0].children[0];
|
||||
const fill = svgPath.getAttribute('fill');
|
||||
const state =
|
||||
fill === theme.colorPrimary
|
||||
? CHECKED
|
||||
: fill === theme.colorTextSecondary
|
||||
? INDETERMINATE
|
||||
: UNCHECKED;
|
||||
onStateDetected(state);
|
||||
}, [name, theme, onStateDetected]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getCheckboxState(name: string): CheckboxState {
|
||||
const element = screen.getByRole('link', { name });
|
||||
const svgPath = getCheckboxIcon(element).children[1].children[0].children[0];
|
||||
const fill = svgPath.getAttribute('fill');
|
||||
return fill === supersetTheme.colorPrimary
|
||||
? CHECKED
|
||||
: fill === supersetTheme.colorTextSecondary
|
||||
? INDETERMINATE
|
||||
: UNCHECKED;
|
||||
let detectedState: CheckboxState = UNCHECKED;
|
||||
render(
|
||||
<CheckboxStateDetector
|
||||
name={name}
|
||||
onStateDetected={state => {
|
||||
detectedState = state;
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
return detectedState;
|
||||
}
|
||||
|
||||
// Replace the original clickCheckbox function with the async version
|
||||
|
||||
@@ -27,7 +27,7 @@ import fetchMock from 'fetch-mock';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { ChartCreation } from 'src/pages/ChartCreation';
|
||||
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
|
||||
import { supersetTheme } from '@superset-ui/core';
|
||||
import { DEFAULT_THEME } from '@superset-ui/core';
|
||||
|
||||
jest.mock('src/components/DynamicPlugins', () => ({
|
||||
usePluginContext: () => ({
|
||||
@@ -93,7 +93,7 @@ async function renderComponent(user = mockUser) {
|
||||
<ChartCreation
|
||||
user={user}
|
||||
addSuccessToast={() => null}
|
||||
theme={supersetTheme}
|
||||
theme={DEFAULT_THEME}
|
||||
{...routeProps}
|
||||
/>,
|
||||
{
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
type ThemeStorage,
|
||||
Theme,
|
||||
ThemeMode,
|
||||
themeObject as supersetThemeObject,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
getAntdConfig,
|
||||
@@ -105,8 +104,8 @@ export class ThemeController {
|
||||
constructor({
|
||||
storage = new LocalStorageAdapter(),
|
||||
modeStorageKey = STORAGE_KEYS.THEME_MODE,
|
||||
themeObject = supersetThemeObject,
|
||||
defaultTheme = (supersetThemeObject.theme as AnyThemeConfig) ?? {},
|
||||
themeObject = Theme.fromConfig(),
|
||||
defaultTheme = Theme.fromConfig().theme as AnyThemeConfig,
|
||||
onChange = undefined,
|
||||
}: ThemeControllerOptions = {}) {
|
||||
this.storage = storage;
|
||||
|
||||
@@ -26,7 +26,6 @@ import { Route, BrowserRouter } from 'react-router-dom';
|
||||
import { CacheProvider } from '@emotion/react';
|
||||
import { QueryParamProvider } from 'use-query-params';
|
||||
import createCache from '@emotion/cache';
|
||||
import { ThemeProvider, theme } from '@superset-ui/core';
|
||||
import Menu from 'src/features/home/Menu';
|
||||
import getBootstrapData from 'src/utils/getBootstrapData';
|
||||
import { setupStore } from './store';
|
||||
@@ -44,18 +43,16 @@ const emotionCache = createCache({
|
||||
const app = (
|
||||
// @ts-ignore: emotion types defs are incompatible between core and cache
|
||||
<CacheProvider value={emotionCache}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<QueryParamProvider
|
||||
ReactRouterRoute={Route}
|
||||
stringifyOptions={{ encode: false }}
|
||||
>
|
||||
<Menu data={menu} />
|
||||
</QueryParamProvider>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
</ThemeProvider>
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<QueryParamProvider
|
||||
ReactRouterRoute={Route}
|
||||
stringifyOptions={{ encode: false }}
|
||||
>
|
||||
<Menu data={menu} />
|
||||
</QueryParamProvider>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
</CacheProvider>
|
||||
);
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ import {
|
||||
DatasourceType,
|
||||
ChartProps,
|
||||
Behavior,
|
||||
supersetTheme,
|
||||
Metric,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import { transformProps, TableChartProps } from './transformProps';
|
||||
|
||||
interface ExtendedMetric extends Omit<Metric, 'uuid'> {
|
||||
@@ -111,7 +111,6 @@ function createMockChartProps(
|
||||
queriesData: defaultQueryData,
|
||||
width: 800,
|
||||
behaviors: [] as Behavior[],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
const tableChartProps: TableChartProps = {
|
||||
|
||||
Reference in New Issue
Block a user