mirror of
https://github.com/apache/superset.git
synced 2026-04-12 20:57:55 +00:00
refactor: Replace react-bootstrap Tabs with Antd Tabs in DashboardBuilder (#11160)
* Replace tabs in DashboardBuilder * Fix tests * Fix styling of anchor * Fix * Fix cypress test * Fix tests * Fix e2e tests * Use data-tests * Move tabs styles from superset.less to Emotion * Restyle tabs in DashboardBuilder * Test fix * Fix styling
This commit is contained in:
committed by
GitHub
parent
6c6ded139b
commit
a874b14a8a
@@ -22,10 +22,8 @@ import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
|
||||
import DeleteComponentModal from 'src/dashboard/components/DeleteComponentModal';
|
||||
import DragDroppable from 'src/dashboard/components/dnd/DragDroppable';
|
||||
import EditableTitle from 'src/components/EditableTitle';
|
||||
import WithPopoverMenu from 'src/dashboard/components/menu/WithPopoverMenu';
|
||||
import Tab, {
|
||||
RENDER_TAB,
|
||||
RENDER_TAB_CONTENT,
|
||||
@@ -96,42 +94,6 @@ describe('Tabs', () => {
|
||||
'New title',
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a WithPopoverMenu', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find(WithPopoverMenu)).toExist();
|
||||
});
|
||||
|
||||
it('should render a DeleteComponentModal when focused if its not the only tab', () => {
|
||||
let wrapper = setup();
|
||||
wrapper.find(WithPopoverMenu).simulate('click'); // focus
|
||||
expect(wrapper.find(DeleteComponentModal)).not.toExist();
|
||||
|
||||
wrapper = setup({ editMode: true });
|
||||
wrapper.find(WithPopoverMenu).simulate('click');
|
||||
expect(wrapper.find(DeleteComponentModal)).toExist();
|
||||
|
||||
wrapper = setup({
|
||||
editMode: true,
|
||||
parentComponent: {
|
||||
...props.parentComponent,
|
||||
children: props.parentComponent.children.slice(0, 1),
|
||||
},
|
||||
});
|
||||
wrapper.find(WithPopoverMenu).simulate('click');
|
||||
expect(wrapper.find(DeleteComponentModal)).not.toExist();
|
||||
});
|
||||
|
||||
it('should show modal when clicked delete icon', () => {
|
||||
const deleteComponent = sinon.spy();
|
||||
const wrapper = setup({ editMode: true, deleteComponent });
|
||||
wrapper.find(WithPopoverMenu).simulate('click'); // focus
|
||||
wrapper.find('.icon-button').simulate('click');
|
||||
|
||||
const modal = document.getElementsByClassName('ant-modal');
|
||||
expect(modal).toHaveLength(1);
|
||||
expect(deleteComponent.callCount).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderType=RENDER_TAB_CONTENT', () => {
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
*/
|
||||
import { Provider } from 'react-redux';
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
import { Tabs as BootstrapTabs, Tab as BootstrapTab } from 'react-bootstrap';
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import { LineEditableTabs } from 'src/common/components/Tabs';
|
||||
import { Modal } from 'src/common/components';
|
||||
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
|
||||
import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton';
|
||||
import HoverMenu from 'src/dashboard/components/menu/HoverMenu';
|
||||
@@ -54,6 +55,7 @@ describe('Tabs', () => {
|
||||
deleteComponent() {},
|
||||
updateComponents() {},
|
||||
logEvent() {},
|
||||
setMountedTab() {},
|
||||
};
|
||||
|
||||
function setup(overrideProps) {
|
||||
@@ -65,10 +67,6 @@ describe('Tabs', () => {
|
||||
<Tabs {...props} {...overrideProps} />
|
||||
</WithDragDropContext>
|
||||
</Provider>,
|
||||
{
|
||||
wrappingComponent: ThemeProvider,
|
||||
wrappingComponentProps: { theme: supersetTheme },
|
||||
},
|
||||
);
|
||||
return wrapper;
|
||||
}
|
||||
@@ -79,31 +77,23 @@ describe('Tabs', () => {
|
||||
expect(wrapper.find(DragDroppable)).toExist();
|
||||
});
|
||||
|
||||
it('should render BootstrapTabs', () => {
|
||||
it('should render non-editable tabs', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find(BootstrapTabs)).toExist();
|
||||
expect(wrapper.find(LineEditableTabs)).toExist();
|
||||
expect(wrapper.find('.ant-tabs-nav-add').exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should set animation=true, mountOnEnter=true, and unmounOnExit=false on BootstrapTabs for perf', () => {
|
||||
it('should render a tab pane for each child', () => {
|
||||
const wrapper = setup();
|
||||
const tabProps = wrapper.find(BootstrapTabs).props();
|
||||
expect(tabProps.animation).toBe(true);
|
||||
expect(tabProps.mountOnEnter).toBe(true);
|
||||
expect(tabProps.unmountOnExit).toBe(false);
|
||||
});
|
||||
|
||||
it('should render a BootstrapTab for each child', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find(BootstrapTab)).toHaveLength(
|
||||
expect(wrapper.find(LineEditableTabs.TabPane)).toHaveLength(
|
||||
props.component.children.length,
|
||||
);
|
||||
});
|
||||
|
||||
it('should render an extra (+) BootstrapTab in editMode', () => {
|
||||
it('should render editable tabs in editMode', () => {
|
||||
const wrapper = setup({ editMode: true });
|
||||
expect(wrapper.find(BootstrapTab)).toHaveLength(
|
||||
props.component.children.length + 1,
|
||||
);
|
||||
expect(wrapper.find(LineEditableTabs)).toExist();
|
||||
expect(wrapper.find('.ant-tabs-nav-add')).toExist();
|
||||
});
|
||||
|
||||
it('should render a DashboardComponent for each child', () => {
|
||||
@@ -118,7 +108,7 @@ describe('Tabs', () => {
|
||||
const createComponent = sinon.spy();
|
||||
const wrapper = setup({ editMode: true, createComponent });
|
||||
wrapper
|
||||
.find('.dashboard-component-tabs .nav-tabs a')
|
||||
.find('[data-test="dashboard-component-tabs"] .ant-tabs-nav-add')
|
||||
.last()
|
||||
.simulate('click');
|
||||
|
||||
@@ -129,7 +119,7 @@ describe('Tabs', () => {
|
||||
const onChangeTab = sinon.spy();
|
||||
const wrapper = setup({ editMode: true, onChangeTab });
|
||||
wrapper
|
||||
.find('.dashboard-component-tabs .nav-tabs a')
|
||||
.find('[data-test="dashboard-component-tabs"] .ant-tabs-tab')
|
||||
.at(1) // will not call if it is already selected
|
||||
.simulate('click');
|
||||
|
||||
@@ -140,7 +130,9 @@ describe('Tabs', () => {
|
||||
const onChangeTab = sinon.spy();
|
||||
const wrapper = setup({ editMode: true, onChangeTab });
|
||||
wrapper
|
||||
.find('.dashboard-component-tabs .nav-tabs a .short-link-trigger')
|
||||
.find(
|
||||
'[data-test="dashboard-component-tabs"] .ant-tabs-tab [data-test="short-link-button"]',
|
||||
)
|
||||
.at(1) // will not call if it is already selected
|
||||
.simulate('click');
|
||||
|
||||
@@ -186,4 +178,13 @@ describe('Tabs', () => {
|
||||
wrapper = shallow(<Tabs {...directLinkProps} />);
|
||||
expect(wrapper.state('tabIndex')).toBe(1);
|
||||
});
|
||||
|
||||
it('should render Modal when clicked remove tab button', () => {
|
||||
const deleteComponent = sinon.spy();
|
||||
const modalMock = jest.spyOn(Modal, 'confirm');
|
||||
const wrapper = setup({ editMode: true, deleteComponent });
|
||||
wrapper.find('.ant-tabs-tab-remove').at(0).simulate('click');
|
||||
expect(modalMock.mock.calls).toHaveLength(1);
|
||||
expect(deleteComponent.callCount).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user