Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(table-viz): rewrite with react-table and add query mode switch mode #10113

Merged
merged 7 commits into from Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -61,7 +61,7 @@ describe('Dashboard filter', () => {
expect(nodes).to.have.length(9);
});

cy.get('.Select__control input[type=text]').first().blur();
cy.get('.Select__control input[type=text]').first().focus().blur();

// should hide the filter indicator
cy.get('.filter-indicator')
Expand Down
20,123 changes: 8,183 additions & 11,940 deletions superset-frontend/package-lock.json

Large diffs are not rendered by default.

29 changes: 15 additions & 14 deletions superset-frontend/package.json
Expand Up @@ -61,14 +61,14 @@
"@emotion/core": "^10.0.28",
"@superset-ui/chart": "^0.14.1",
"@superset-ui/chart-composition": "^0.14.1",
"@superset-ui/color": "^0.14.1",
"@superset-ui/color": "^0.14.2",
"@superset-ui/connection": "^0.14.0",
"@superset-ui/chart-controls": "^0.14.1",
"@superset-ui/chart-controls": "^0.14.2",
"@superset-ui/core": "^0.14.0",
"@superset-ui/dimension": "^0.14.0",
"@superset-ui/legacy-plugin-chart-calendar": "^0.14.1",
"@superset-ui/legacy-plugin-chart-chord": "^0.14.1",
"@superset-ui/legacy-plugin-chart-country-map": "^0.14.1",
"@superset-ui/legacy-plugin-chart-country-map": "^0.14.2",
"@superset-ui/legacy-plugin-chart-event-flow": "^0.14.1",
"@superset-ui/legacy-plugin-chart-force-directed": "^0.14.1",
"@superset-ui/legacy-plugin-chart-heatmap": "^0.14.1",
Expand All @@ -85,7 +85,7 @@
"@superset-ui/legacy-plugin-chart-sankey": "^0.14.1",
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.14.1",
"@superset-ui/legacy-plugin-chart-sunburst": "^0.14.1",
"@superset-ui/legacy-plugin-chart-table": "^0.14.1",
"@superset-ui/plugin-chart-table": "^0.14.2",
"@superset-ui/legacy-plugin-chart-treemap": "^0.14.1",
"@superset-ui/legacy-plugin-chart-world-map": "^0.14.1",
"@superset-ui/legacy-preset-chart-big-number": "^0.14.1",
Expand All @@ -96,7 +96,7 @@
"@superset-ui/preset-chart-xy": "^0.14.1",
"@superset-ui/query": "^0.14.1",
"@superset-ui/style": "^0.14.0",
"@superset-ui/superset-ui": "^0.14.1",
"@superset-ui/superset-ui": "^0.14.2",
"@superset-ui/time-format": "^0.14.1",
"@superset-ui/translation": "^0.14.0",
"@superset-ui/validator": "^0.14.1",
Expand All @@ -110,6 +110,7 @@
"@types/redux-localstorage": "^1.0.8",
"@types/rison": "0.0.6",
"@vx/responsive": "^0.0.195",
"memoize-one": "^5.1.1",
"abortcontroller-polyfill": "^1.1.9",
"aphrodite": "^2.3.1",
"array-move": "^2.2.1",
Expand Down Expand Up @@ -166,7 +167,7 @@
"react-split": "^2.0.4",
"react-sticky": "^6.0.2",
"react-syntax-highlighter": "^7.0.4",
"react-table": "^7.0.4",
"react-table": "^7.2.1",
"react-transition-group": "^2.5.3",
"react-ultimate-pagination": "^1.2.0",
"react-virtualized": "9.19.1",
Expand All @@ -178,7 +179,7 @@
"redux-localstorage": "^0.4.1",
"redux-thunk": "^2.1.0",
"redux-undo": "^1.0.0-beta9-9-7",
"regenerator-runtime": "^0.13.3",
"regenerator-runtime": "^0.13.5",
"rison": "^0.1.1",
"shortid": "^2.2.6",
"urijs": "^1.18.10",
Expand All @@ -202,19 +203,19 @@
"@svgr/webpack": "^5.4.0",
"@types/classnames": "^2.2.9",
"@types/dom-to-image": "^2.6.0",
"@types/jest": "^25.1.4",
"@types/jest": "^26.0.3",
"@types/jquery": "^3.3.32",
"@types/react": "^16.9.38",
"@types/react-dom": "^16.9.8",
"@types/react-json-tree": "^0.6.11",
"@types/react-redux": "^7.1.7",
"@types/react-table": "^7.0.2",
"@types/react-table": "^7.0.19",
"@types/react-ultimate-pagination": "^1.2.0",
"@types/yargs": "12 - 15",
"@typescript-eslint/eslint-plugin": "^2.20.0",
"@typescript-eslint/parser": "^2.20.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.1.0",
"babel-jest": "^26.1.0",
"babel-loader": "^8.0.6",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-plugin-emotion": "^10.0.29",
Expand All @@ -233,7 +234,7 @@
"eslint-import-resolver-webpack": "^0.10.1",
"eslint-plugin-cypress": "^2.0.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jest": "^21.24.1",
"eslint-plugin-jest": "^23.17.1",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-no-only-tests": "^2.0.1",
"eslint-plugin-prettier": "^3.1.3",
Expand All @@ -244,8 +245,8 @@
"fork-ts-checker-webpack-plugin": "^0.4.9",
"ignore-styles": "^5.0.1",
"imports-loader": "^0.7.1",
"jest": "^25.1.0",
"jsdom": "9.12.0",
"jest": "^26.1.0",
"jsdom": "^16.2.2",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.4.0",
Expand All @@ -261,7 +262,7 @@
"terser-webpack-plugin": "^1.1.0",
"thread-loader": "^1.2.0",
"transform-loader": "^0.2.3",
"ts-jest": "^25.4.0",
"ts-jest": "^26.1.1",
"ts-loader": "^6.2.1",
"typescript": "^3.8.3",
"url-loader": "^1.0.1",
Expand Down
27 changes: 0 additions & 27 deletions superset-frontend/spec/helpers/shim.js
Expand Up @@ -20,7 +20,6 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
import jsdom from 'jsdom';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { configure as configureTranslation } from '@superset-ui/translation';
Expand All @@ -31,39 +30,13 @@ configure({ adapter: new Adapter() });

const exposedProperties = ['window', 'navigator', 'document'];

global.jsdom = jsdom.jsdom;
global.document = global.jsdom('<!doctype html><html><body></body></html>');
global.window = document.defaultView;
global.HTMLElement = window.HTMLElement;

Object.keys(document.defaultView).forEach(property => {
if (typeof global[property] === 'undefined') {
exposedProperties.push(property);
global[property] = document.defaultView[property];
}
});

global.navigator = {
userAgent: 'node.js',
platform: 'linux',
appName: 'Netscape',
};

// Fix `Option is not defined`
// https://stackoverflow.com/questions/39501589/jsdom-option-is-not-defined-when-running-my-mocha-test
global.Option = window.Option;

// Configuration copied from https://github.com/sinonjs/sinon/issues/657
// allowing for sinon.fakeServer to work

global.window = global.document.defaultView;
global.XMLHttpRequest = global.window.XMLHttpRequest;

global.sinon = require('sinon');

global.sinon.useFakeXMLHttpRequest();

global.window.XMLHttpRequest = global.XMLHttpRequest;
global.window.location = { href: 'about:blank' };
global.window.performance = { now: () => new Date().getTime() };
global.$ = require('jquery')(global.window);
Expand Down
86 changes: 47 additions & 39 deletions superset-frontend/spec/javascripts/components/AsyncSelect_spec.jsx
Expand Up @@ -62,53 +62,61 @@ describe('AsyncSelect', () => {
});

describe('auto select', () => {
it('should not call onChange if autoSelect=false', done => {
expect.assertions(2);
it('should not call onChange if autoSelect=false', () => {
return new Promise(done => {
expect.assertions(2);

const onChangeSpy = jest.fn();
shallow(<AsyncSelect {...mockedProps} onChange={onChangeSpy} />);
const onChangeSpy = jest.fn();
shallow(<AsyncSelect {...mockedProps} onChange={onChangeSpy} />);

setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(0);
done();
setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(0);
done();
});
});
});

it('should auto select the first option if autoSelect=true', done => {
expect.assertions(3);

const onChangeSpy = jest.fn();
const wrapper = shallow(
<AsyncSelect {...mockedProps} onChange={onChangeSpy} autoSelect />,
);

setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(1);
expect(onChangeSpy).toBeCalledWith(wrapper.instance().state.options[0]);
done();
it('should auto select the first option if autoSelect=true', () => {
return new Promise(done => {
expect.assertions(3);

const onChangeSpy = jest.fn();
const wrapper = shallow(
<AsyncSelect {...mockedProps} onChange={onChangeSpy} autoSelect />,
);

setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(1);
expect(onChangeSpy).toBeCalledWith(
wrapper.instance().state.options[0],
);
done();
});
});
});

it('should not auto select when value prop is set and autoSelect=true', done => {
expect.assertions(3);

const onChangeSpy = jest.fn();
const wrapper = shallow(
<AsyncSelect
{...mockedProps}
value={2}
onChange={onChangeSpy}
autoSelect
/>,
);

setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(0);
expect(wrapper.find(Select)).toHaveLength(1);
done();
it('should not auto select when value prop is set and autoSelect=true', () => {
return new Promise(done => {
expect.assertions(3);

const onChangeSpy = jest.fn();
const wrapper = shallow(
<AsyncSelect
{...mockedProps}
value={2}
onChange={onChangeSpy}
autoSelect
/>,
);

setTimeout(() => {
expect(fetchMock.calls(dataGlob)).toHaveLength(1);
expect(onChangeSpy.mock.calls).toHaveLength(0);
expect(wrapper.find(Select)).toHaveLength(1);
done();
});
});
});

Expand Down
Expand Up @@ -30,7 +30,7 @@ import Pagination from 'src/components/Pagination';
import { areArraysShallowEqual } from 'src/reduxUtils';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';

export function makeMockLocation(query) {
function makeMockLocation(query) {
const queryStr = encodeURIComponent(query);
return {
protocol: 'http:',
Expand Down Expand Up @@ -292,16 +292,14 @@ Array [
...mockedProps,
filters: [...mockedProps.filters, { id: 'some_column' }],
};
try {
expect(() => {
shallow(<ListView {...props} />, {
wrappingComponent: ThemeProvider,
wrappingComponentProps: { theme: supersetTheme },
});
} catch (e) {
expect(e).toMatchInlineSnapshot(
`[ListViewError: Invalid filter config, some_column is not present in columns]`,
);
}
}).toThrowErrorMatchingInlineSnapshot(
'"Invalid filter config, some_column is not present in columns"',
);
});
});

Expand Down
Expand Up @@ -176,7 +176,7 @@ describe('TableSelector', () => {
});

// Test needs to be fixed: Github issue #7768
xit('should dispatch a danger toast on error', () => {
it.skip('should dispatch a danger toast on error', () => {
fetchMock.get(
FETCH_TABLES_GLOB,
{ throws: 'error' },
Expand Down Expand Up @@ -218,7 +218,7 @@ describe('TableSelector', () => {
});

// Test needs to be fixed: Github issue #7768
xit('should dispatch a danger toast on error', () => {
it.skip('should dispatch a danger toast on error', () => {
const handleErrors = sinon.stub();
expect(handleErrors.callCount).toBe(0);
wrapper.setProps({ handleErrors });
Expand Down
Expand Up @@ -70,25 +70,29 @@ describe('ChangeDatasourceModal', () => {
expect(wrapper.find(Modal)).toHaveLength(1);
});

it('fetches datasources', done => {
inst.onEnterModal();
setTimeout(() => {
expect(fetchMock.calls(DATASOURCES_ENDPOINT)).toHaveLength(1);
fetchMock.reset();
done();
}, 0);
it('fetches datasources', () => {
return new Promise(done => {
inst.onEnterModal();
setTimeout(() => {
expect(fetchMock.calls(DATASOURCES_ENDPOINT)).toHaveLength(1);
fetchMock.reset();
done();
}, 0);
});
});

it('changes the datasource', done => {
fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD);
inst.selectDatasource(datasourceData);
setTimeout(() => {
expect(fetchMock.calls(DATASOURCE_ENDPOINT)).toHaveLength(1);
expect(props.onDatasourceSave.getCall(0).args[0]).toEqual(
DATASOURCE_PAYLOAD,
);
fetchMock.reset();
done();
}, 0);
it('changes the datasource', () => {
return new Promise(done => {
fetchMock.get(DATASOURCE_ENDPOINT, DATASOURCE_PAYLOAD);
inst.selectDatasource(datasourceData);
setTimeout(() => {
expect(fetchMock.calls(DATASOURCE_ENDPOINT)).toHaveLength(1);
expect(props.onDatasourceSave.getCall(0).args[0]).toEqual(
DATASOURCE_PAYLOAD,
);
fetchMock.reset();
done();
}, 0);
});
});
});
Expand Up @@ -70,17 +70,19 @@ describe('DatasourceEditor', () => {
expect(wrapper.find(Tabs)).toHaveLength(1);
});

it('makes an async request', done => {
wrapper.setState({ activeTabKey: 2 });
const syncButton = wrapper.find('.sync-from-source');
expect(syncButton).toHaveLength(1);
syncButton.simulate('click');
it('makes an async request', () => {
return new Promise(done => {
wrapper.setState({ activeTabKey: 2 });
const syncButton = wrapper.find('.sync-from-source');
expect(syncButton).toHaveLength(1);
syncButton.simulate('click');

setTimeout(() => {
expect(fetchMock.calls(DATASOURCE_ENDPOINT)).toHaveLength(1);
fetchMock.reset();
done();
}, 0);
setTimeout(() => {
expect(fetchMock.calls(DATASOURCE_ENDPOINT)).toHaveLength(1);
fetchMock.reset();
done();
}, 0);
});
});

it('merges columns', () => {
Expand Down