Transformations: Wrap sql expression tile under FF (#114030)
* Transformations: Add empty state placeholder with SQL expression and transformation cards - Extract TransformationCard and SqlExpressionCard into separate reusable components - Add new empty transformations placeholder UI behind transformationsEmptyPlaceholder feature toggle - Add auto-scroll to SQL expression when navigating from transformations tab - Add analytics tracking for transformation interactions - Split EmptyTransformationsMessage into Legacy and New variants for easier toggle removal * add tests
This commit is contained in:
+43
-16
@@ -3,13 +3,10 @@ import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { standardTransformersRegistry } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import config from 'app/core/config';
|
||||
import { getStandardTransformers } from 'app/features/transformers/standardTransformers';
|
||||
|
||||
import { LegacyEmptyTransformationsMessage, NewEmptyTransformationsMessage } from './EmptyTransformationsMessage';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
}));
|
||||
import { EmptyTransformationsMessage, LegacyEmptyTransformationsMessage } from './EmptyTransformationsMessage';
|
||||
|
||||
describe('EmptyTransformationsMessage', () => {
|
||||
standardTransformersRegistry.setInit(getStandardTransformers);
|
||||
@@ -20,6 +17,11 @@ describe('EmptyTransformationsMessage', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Set up feature toggles
|
||||
config.featureToggles = config.featureToggles || {};
|
||||
config.featureToggles.transformationsEmptyPlaceholder = false;
|
||||
config.featureToggles.sqlExpressions = true;
|
||||
});
|
||||
|
||||
describe('LegacyEmptyTransformationsMessage', () => {
|
||||
@@ -41,10 +43,16 @@ describe('EmptyTransformationsMessage', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('NewEmptyTransformationsMessage', () => {
|
||||
it('should render transformation cards when both onGoToQueries and onAddTransformation are provided', () => {
|
||||
describe('EmptyTransformationsMessage (new UI)', () => {
|
||||
beforeEach(() => {
|
||||
config.featureToggles.transformationsEmptyPlaceholder = true;
|
||||
});
|
||||
|
||||
it('should render SQL expression card and transformation cards when sqlExpressions toggle is enabled', () => {
|
||||
config.featureToggles.sqlExpressions = true;
|
||||
|
||||
render(
|
||||
<NewEmptyTransformationsMessage
|
||||
<EmptyTransformationsMessage
|
||||
onShowPicker={onShowPicker}
|
||||
onGoToQueries={onGoToQueries}
|
||||
onAddTransformation={onAddTransformation}
|
||||
@@ -59,30 +67,49 @@ describe('EmptyTransformationsMessage', () => {
|
||||
expect(screen.getByText('Filter data by values')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call onShowPicker when "Show more" button is clicked', async () => {
|
||||
const user = userEvent.setup();
|
||||
it('should not show SQL expression card when sqlExpressions toggle is disabled', () => {
|
||||
config.featureToggles.sqlExpressions = false;
|
||||
|
||||
render(
|
||||
<NewEmptyTransformationsMessage
|
||||
<EmptyTransformationsMessage
|
||||
onShowPicker={onShowPicker}
|
||||
onGoToQueries={onGoToQueries}
|
||||
onAddTransformation={onAddTransformation}
|
||||
/>
|
||||
);
|
||||
|
||||
const button = screen.getByTestId(selectors.components.Transforms.addTransformationButton);
|
||||
await user.click(button);
|
||||
expect(screen.queryByText('SQL Expressions')).not.toBeInTheDocument();
|
||||
// But should still show transformation cards
|
||||
expect(screen.getByText('Organize fields by name')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(onShowPicker).toHaveBeenCalledTimes(1);
|
||||
it('should call onGoToQueries when SQL expression card is clicked', async () => {
|
||||
config.featureToggles.sqlExpressions = true;
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(
|
||||
<EmptyTransformationsMessage
|
||||
onShowPicker={onShowPicker}
|
||||
onGoToQueries={onGoToQueries}
|
||||
onAddTransformation={onAddTransformation}
|
||||
/>
|
||||
);
|
||||
|
||||
const sqlCard = screen.getByTestId('go-to-queries-button');
|
||||
const button = sqlCard.querySelector('button');
|
||||
await user.click(button!);
|
||||
|
||||
expect(onGoToQueries).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not show SQL transformation card when onGoToQueries is not provided', () => {
|
||||
render(<NewEmptyTransformationsMessage onShowPicker={onShowPicker} onAddTransformation={onAddTransformation} />);
|
||||
render(<EmptyTransformationsMessage onShowPicker={onShowPicker} onAddTransformation={onAddTransformation} />);
|
||||
|
||||
expect(screen.queryByText('SQL Expressions')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show transformation cards grid when neither onGoToQueries nor onAddTransformation are provided', () => {
|
||||
render(<NewEmptyTransformationsMessage onShowPicker={onShowPicker} />);
|
||||
render(<EmptyTransformationsMessage onShowPicker={onShowPicker} />);
|
||||
|
||||
expect(screen.queryByText('SQL Expressions')).not.toBeInTheDocument();
|
||||
|
||||
|
||||
+8
-2
@@ -25,6 +25,9 @@ const TRANSFORMATION_IDS = [
|
||||
DataTransformerID.filterByValue,
|
||||
];
|
||||
|
||||
const GRID_COLUMNS_WITH_SQL = 5;
|
||||
const GRID_COLUMNS_WITHOUT_SQL = 4;
|
||||
|
||||
export function LegacyEmptyTransformationsMessage({ onShowPicker }: { onShowPicker: () => void }) {
|
||||
return (
|
||||
<Box alignItems="center" padding={4}>
|
||||
@@ -89,12 +92,15 @@ export function NewEmptyTransformationsMessage(props: EmptyTransformationsProps)
|
||||
props.onShowPicker();
|
||||
};
|
||||
|
||||
const showSqlCard = hasGoToQueries && config.featureToggles.sqlExpressions;
|
||||
const gridColumns = showSqlCard ? GRID_COLUMNS_WITH_SQL : GRID_COLUMNS_WITHOUT_SQL;
|
||||
|
||||
return (
|
||||
<Box alignItems="center" padding={4}>
|
||||
<Stack direction="column" alignItems="center" gap={4}>
|
||||
{(hasAddTransformation || hasGoToQueries) && (
|
||||
<Grid columns={5} gap={1}>
|
||||
{hasGoToQueries && (
|
||||
<Grid columns={gridColumns} gap={1}>
|
||||
{showSqlCard && (
|
||||
<SqlExpressionCard
|
||||
name={t('dashboard-scene.empty-transformations-message.sql-name', 'SQL Expressions')}
|
||||
description={t(
|
||||
|
||||
+27
-3
@@ -167,9 +167,12 @@ describe('PanelDataTransformationsTab', () => {
|
||||
expect(reduce).toBeNull();
|
||||
});
|
||||
|
||||
it('renders SQL transformation card in empty state when feature toggle is enabled', async () => {
|
||||
const originalFeatureToggle = config.featureToggles.transformationsEmptyPlaceholder;
|
||||
it('renders SQL transformation card in empty state when feature toggles are enabled', async () => {
|
||||
const originalTransformationsToggle = config.featureToggles.transformationsEmptyPlaceholder;
|
||||
const originalSqlToggle = config.featureToggles.sqlExpressions;
|
||||
|
||||
config.featureToggles.transformationsEmptyPlaceholder = true;
|
||||
config.featureToggles.sqlExpressions = true;
|
||||
|
||||
try {
|
||||
const modelMock = createModelMock(mockData);
|
||||
@@ -179,7 +182,28 @@ describe('PanelDataTransformationsTab', () => {
|
||||
expect(screen.getByText('SQL Expressions')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('go-to-queries-button')).toBeInTheDocument();
|
||||
} finally {
|
||||
config.featureToggles.transformationsEmptyPlaceholder = originalFeatureToggle;
|
||||
config.featureToggles.transformationsEmptyPlaceholder = originalTransformationsToggle;
|
||||
config.featureToggles.sqlExpressions = originalSqlToggle;
|
||||
}
|
||||
});
|
||||
|
||||
it('does not render SQL transformation card when sqlExpressions toggle is disabled', async () => {
|
||||
const originalTransformationsToggle = config.featureToggles.transformationsEmptyPlaceholder;
|
||||
const originalSqlToggle = config.featureToggles.sqlExpressions;
|
||||
|
||||
config.featureToggles.transformationsEmptyPlaceholder = true;
|
||||
config.featureToggles.sqlExpressions = false;
|
||||
|
||||
try {
|
||||
const modelMock = createModelMock(mockData);
|
||||
render(<PanelDataTransformationsTabRendered model={modelMock}></PanelDataTransformationsTabRendered>);
|
||||
|
||||
// Should not show SQL transformation card
|
||||
expect(screen.queryByText('SQL Expressions')).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('go-to-queries-button')).not.toBeInTheDocument();
|
||||
} finally {
|
||||
config.featureToggles.transformationsEmptyPlaceholder = originalTransformationsToggle;
|
||||
config.featureToggles.sqlExpressions = originalSqlToggle;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user