diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.test.tsx new file mode 100644 index 00000000000..2a16f4010f8 --- /dev/null +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.test.tsx @@ -0,0 +1,183 @@ +/** + * 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 { configureStore } from '@reduxjs/toolkit'; +import { Provider } from 'react-redux'; +import { + fireEvent, + render, + screen, + userEvent, +} from 'spec/helpers/testing-library'; +import { AdhocColumn } from '@superset-ui/core'; +import { ColumnMeta } from '@superset-ui/chart-controls'; +import ColumnSelectPopoverTriggerWrapper from './ColumnSelectPopoverTrigger'; + +const createStore = (datasource = {}) => + configureStore({ + reducer: { + explore: () => ({ + datasource, + }), + }, + }); + +const defaultColumns: ColumnMeta[] = [ + { + column_name: 'test_column', + verbose_name: 'Test Column', + type: 'STRING', + }, +]; + +const firstAdhocColumn: AdhocColumn = { + label: 'First Custom Column', + sqlExpression: '', + expressionType: 'SQL', +}; + +const secondAdhocColumn: AdhocColumn = { + label: 'Second Custom Column', + sqlExpression: 'SUM(amount)', + expressionType: 'SQL', +}; + +const defaultProps = { + columns: defaultColumns, + onColumnEdit: jest.fn(), + children: , +}; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +test('should handle creating two columns with proper label reset', async () => { + const store = createStore(); + const onColumnEditMock = jest.fn(); + + const { rerender } = render( + + + , + ); + + fireEvent.click(screen.getByText('Trigger')); + expect(screen.getByText('My column')).toBeInTheDocument(); + + const firstSqlInput = screen.getByText('Custom SQL'); + fireEvent.click(firstSqlInput!); + expect(screen.queryByText('Click to edit label')).not.toBeInTheDocument(); + const firstLabelInput = await screen.findByTestId( + 'AdhocMetricEditTitle#trigger', + ); + userEvent.type(firstLabelInput, 'First Custom Column'); + fireEvent.click(screen.getByTestId('ColumnEdit#save')); + + expect(onColumnEditMock).toHaveBeenCalledWith( + expect.objectContaining({ + expressionType: 'SQL', + label: 'First Custom Column', + sqlExpression: '', + }), + ); + + rerender( + + + , + ); + + fireEvent.click(screen.getByText('Trigger')); + expect(screen.getByText('My column')).toBeInTheDocument(); + + const secondSqlInput = screen.getByText('Custom SQL'); + fireEvent.click(secondSqlInput!); + expect(screen.queryByText('Click to edit label')).not.toBeInTheDocument(); + const secondLabelInput = await screen.findByTestId( + 'AdhocMetricEditTitle#trigger', + ); + userEvent.type(secondLabelInput, 'Second Custom Column'); + fireEvent.click(screen.getByTestId('ColumnEdit#save')); + + expect(onColumnEditMock).toHaveBeenLastCalledWith( + expect.objectContaining({ + expressionType: 'SQL', + label: 'Second Custom Column', + sqlExpression: '', + }), + ); + + expect(onColumnEditMock).toHaveBeenCalledTimes(2); +}); + +test('should show correct labels when switching between multiple existing columns', async () => { + const store = createStore(); + const { rerender } = render( + + + , + ); + + fireEvent.click(screen.getByText('Trigger')); + expect(screen.getByTestId('AdhocMetricEditTitle#trigger')).toHaveTextContent( + 'First Custom Column', + ); + + fireEvent.click(screen.getByText('Close')); + + rerender( + + + , + ); + + fireEvent.click(screen.getByText('Trigger')); + + expect(screen.getByTestId('AdhocMetricEditTitle#trigger')).toHaveTextContent( + 'Second Custom Column', + ); + fireEvent.click(screen.getByText('Close')); + + rerender( + + + , + ); + + fireEvent.click(screen.getByText('Trigger')); + expect(screen.getByText('My column')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx index 935b570e3aa..c8729b69833 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx @@ -92,10 +92,6 @@ const ColumnSelectPopoverTriggerInner = ({ initialPopoverLabel = editedColumn.label || defaultPopoverLabel; } - useEffect(() => { - setPopoverLabel(initialPopoverLabel); - }, [initialPopoverLabel, popoverVisible]); - const togglePopover = useCallback((visible: boolean) => { setPopoverVisible(visible); }, []); @@ -121,6 +117,13 @@ const ColumnSelectPopoverTriggerInner = ({ setIsTitleEditDisabled(tab !== editableTitleTab); }, []); + useEffect(() => { + setPopoverLabel(initialPopoverLabel); + if (!visible) { + setHasCustomLabel(false); + } + }, [initialPopoverLabel, visible]); + const overlayContent = useMemo( () => (