Skip to content

Commit

Permalink
feat: Sqllab to Explore UX improvements (#11755)
Browse files Browse the repository at this point in the history
* create boiler modal component

* hello world modal

* setup modal flow

* setup savemodal for components

* flake8

* fix onclick reference

* working create datasource boiler

* saving spot for callback on text input

* working dataset with input box

* working redirect on completion

* get data for owners dropdown

* fix build with pull from master

* fix the filteroption

* 💯

* move state to upper component

* add overwrite state

* hacked overwrite process

* linting

* fix filter

* cleaning up the coe

* Delete preset.code-workspace

* remove unused code

* remove visualize

* update default value

* remove unneeded vars

* checkout package-lock.json

* linting

* get user id

* remove page filter

* setup proper call for updating columns in dataset

* add move to explore flow

* linting

* add param for overriding columns

* linting

* change title

* fix some tings

* cleanup

* linting

* add types in some places

* save toast

* use moment

* add error toast

* create enum for radio states

* initial state for saving query

* add tpying

* addressing concerns

* update propTypes

* add functionality for CTAS explor btn

* handle CTAS state

* fix onclick to reference upper level component

* formatting

* reset state after closing

* add error message when user doesn't pick an already selected dataset

* remove unneeded todo

* remove styling

* move async calls to api directory

* remove console.log

* add user id param

* typing

* littty

* move put to seperate file

* save

* dsf

* fix typing errors

* adding more types

* fix typing erros

* linting

* add basic spec test

* create dataset modal

* add components reference

* Rename SaveDatasetModal_spec.jsx to SaveDatasetModal_spec.tsx

* remove sinon for now

* fix typing errors on modal files

* fix linting

* address comments

* attempt to fix linting

* add props

* fix test

* fix the linting

* yerp

* fix this references

* spaces

* handleOverwriteCancel reference cleanup

* rename bool value for shouldOverwriteDataset

* fix typing for onChange

* you still the best in the world

* fix spec

* align branches

* push

* fix key names

* fix dataset reference

* lowercase

* fix save bug with tiem

* fixed styling

* fix date state after push to explore

* add disabling states

* plz refactor this

* this is working fully now

* do some renaming

* renaming

* remove console.logs

* still refactoring

* remove unneeded code

* remove unneeded variables

* still cleaning

* added interface

* fix typing issues

* cleanup unused code

* fix npm lnit

* fix initial problems

* add props to test

* remove unneeded files

* skip linting

* saving

* this works

* remove old test

* remove old test

* fix linting

* fix broken test

* remove jsx file

* refactoring

* cleanup

* remove comments

* reset user object

* fix functions

* fix this

* reverting CTAS btn flow

* remove onclick

* save frontend work

* allow for database id to be passed as param in body

* use enum

* fix linting

* style alignment

* get rid of .then

* add function to compute default value with tiem

* lit

* remove ts-error

* fix typing
  • Loading branch information
hughhhh authored Dec 9, 2020
1 parent 8164aea commit cc44a2c
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import sinon from 'sinon';
import fetchMock from 'fetch-mock';
import shortid from 'shortid';
import sqlLabReducer from 'src/SqlLab/reducers/index';
import * as actions from 'src/SqlLab/actions/sqlLab';
import ExploreResultsButton from 'src/SqlLab/components/ExploreResultsButton';
import * as exploreUtils from 'src/explore/exploreUtils';
import Button from 'src/components/Button';
Expand Down Expand Up @@ -184,77 +183,5 @@ describe('ExploreResultsButton', () => {
wrapper.instance().buildVizOptions.restore();
fetchMock.reset();
});

it('should build request with correct args', () => {
return new Promise(done => {
wrapper.instance().visualize();

setTimeout(() => {
const calls = fetchMock.calls(visualizeEndpoint);
expect(calls).toHaveLength(1);
const formData = calls[0][1].body;
Object.keys(mockOptions).forEach(key => {
// eslint-disable-next-line no-unused-expressions
expect(formData.get(key)).toBeDefined();
});

done();
});
});
});

it('should export chart and add an info toast', () => {
return new Promise(done => {
const infoToastSpy = sinon.spy();
const datasourceSpy = sinon.stub();

datasourceSpy.callsFake(() => Promise.resolve(visualizationPayload));

wrapper.setProps({
actions: {
addInfoToast: infoToastSpy,
createDatasource: datasourceSpy,
},
});

wrapper.instance().visualize();

setTimeout(() => {
expect(datasourceSpy.callCount).toBe(1);
expect(exploreUtils.exploreChart.callCount).toBe(1);
expect(exploreUtils.exploreChart.getCall(0).args[0].datasource).toBe(
'107__table',
);
expect(infoToastSpy.callCount).toBe(1);
done();
});
});
});

it('should add error toast', () => {
return new Promise(done => {
const dangerToastSpy = sinon.stub(actions, 'addDangerToast');
const datasourceSpy = sinon.stub();

datasourceSpy.callsFake(() => Promise.reject({ error: 'error' }));

wrapper.setProps({
actions: {
createDatasource: datasourceSpy,
addDangerToast: dangerToastSpy,
},
});

wrapper.instance().visualize();

setTimeout(() => {
expect(datasourceSpy.callCount).toBe(1);
expect(exploreUtils.exportChart.callCount).toBe(0);
expect(dangerToastSpy.callCount).toBe(1);
dangerToastSpy.restore();
done();
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ describe('SaveDatasetModal', () => {
userDatasetsOwned: [],
handleSaveDatasetRadioBtnState: () => {},
saveDatasetRadioBtnState: 1,
shouldOverwriteDataset: false,
handleOverwriteCancel: () => {},
handleOverwriteDataset: () => {},
handleOverwriteDatasetOption: () => {},
defaultCreateDatasetValue: 'someDatasets',
shouldOverwriteDataset: false,
userDatasetOptions: [],
disableSaveAndExploreBtn: false,
handleSaveDatasetModalSearch: () => {},
filterAutocompleteOption: () => false,
onChangeAutoComplete: () => {},
};
it('renders a radio group btn', () => {
const wrapper = shallow(<SaveDatasetModal {...mockedProps} />);
Expand Down
56 changes: 2 additions & 54 deletions superset-frontend/src/SqlLab/components/ExploreResultsButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ import { t } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import shortid from 'shortid';

import Modal from 'src/common/components/Modal';
import Button from 'src/components/Button';
import { exploreChart } from '../../explore/exploreUtils';
import * as actions from '../actions/sqlLab';

const propTypes = {
Expand All @@ -37,6 +35,7 @@ const propTypes = {
errorMessage: PropTypes.string,
timeout: PropTypes.number,
database: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired,
};
const defaultProps = {
query: {},
Expand All @@ -45,34 +44,12 @@ const defaultProps = {
class ExploreResultsButton extends React.PureComponent {
constructor(props) {
super(props);
this.visualize = this.visualize.bind(this);
this.onClick = this.onClick.bind(this);
this.getInvalidColumns = this.getInvalidColumns.bind(this);
this.renderInvalidColumnMessage = this.renderInvalidColumnMessage.bind(
this,
);
}

onClick() {
const { timeout } = this.props;
const msg = this.renderInvalidColumnMessage();
if (Math.round(this.getQueryDuration()) > timeout) {
Modal.confirm({
title: t('Explore'),
content: this.renderTimeoutWarning(),
onOk: this.visualize,
icon: null,
});
} else if (msg) {
Modal.warning({
title: t('Explore'),
content: msg,
});
} else {
this.visualize();
}
}

getColumns() {
const { props } = this;
if (
Expand Down Expand Up @@ -123,35 +100,6 @@ class ExploreResultsButton extends React.PureComponent {
};
}

visualize() {
this.props.actions
.createDatasource(this.buildVizOptions())
.then(data => {
const columns = this.getColumns();
const formData = {
datasource: `${data.table_id}__table`,
metrics: [],
groupby: [],
time_range: 'No filter',
viz_type: 'table',
all_columns: columns.map(c => c.name),
row_limit: 1000,
};

this.props.actions.addInfoToast(
t('Creating a data source and creating a new tab'),
);

// open new window for data visualization
exploreChart(formData);
})
.catch(() => {
this.props.actions.addDangerToast(
this.props.errorMessage || t('An error occurred'),
);
});
}

renderTimeoutWarning() {
return (
<Alert bsStyle="warning">
Expand Down Expand Up @@ -203,7 +151,7 @@ class ExploreResultsButton extends React.PureComponent {
<>
<Button
buttonSize="small"
onClick={this.onClick}
onClick={this.props.onClick}
disabled={!allowsSubquery}
tooltip={t('Explore the result set in the data exploration view')}
>
Expand Down
Loading

0 comments on commit cc44a2c

Please sign in to comment.