mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
chore(sqllab): refactor addQueryEditor for new tab (#21711)
This commit is contained in:
parent
a5ff0949a6
commit
0c461497ff
@ -32,6 +32,7 @@ import {
|
|||||||
} from 'src/components/MessageToasts/actions';
|
} from 'src/components/MessageToasts/actions';
|
||||||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||||
import COMMON_ERR_MESSAGES from 'src/utils/errorMessages';
|
import COMMON_ERR_MESSAGES from 'src/utils/errorMessages';
|
||||||
|
import { newQueryTabName } from '../utils/newQueryTabName';
|
||||||
|
|
||||||
export const RESET_STATE = 'RESET_STATE';
|
export const RESET_STATE = 'RESET_STATE';
|
||||||
export const ADD_QUERY_EDITOR = 'ADD_QUERY_EDITOR';
|
export const ADD_QUERY_EDITOR = 'ADD_QUERY_EDITOR';
|
||||||
@ -590,6 +591,22 @@ export function addQueryEditor(queryEditor) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addNewQueryEditor(queryEditor) {
|
||||||
|
return function (dispatch, getState) {
|
||||||
|
const {
|
||||||
|
sqlLab: { queryEditors },
|
||||||
|
} = getState();
|
||||||
|
const name = newQueryTabName(queryEditors || []);
|
||||||
|
|
||||||
|
return dispatch(
|
||||||
|
addQueryEditor({
|
||||||
|
...queryEditor,
|
||||||
|
name,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function cloneQueryToNewTab(query, autorun) {
|
export function cloneQueryToNewTab(query, autorun) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -418,6 +418,28 @@ describe('async actions', () => {
|
|||||||
expect(store.getActions()).toEqual(expectedActions);
|
expect(store.getActions()).toEqual(expectedActions);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('addNewQueryEditor', () => {
|
||||||
|
it('creates new query editor with new tab name', () => {
|
||||||
|
const store = mockStore(initialState);
|
||||||
|
const expectedActions = [
|
||||||
|
{
|
||||||
|
type: actions.ADD_QUERY_EDITOR,
|
||||||
|
queryEditor: {
|
||||||
|
...defaultQueryEditor,
|
||||||
|
id: 'abcd',
|
||||||
|
name: `Untitled Query ${
|
||||||
|
store.getState().sqlLab.queryEditors.length + 1
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const request = actions.addNewQueryEditor(defaultQueryEditor);
|
||||||
|
return request(store.dispatch, store.getState).then(() => {
|
||||||
|
expect(store.getActions()).toEqual(expectedActions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('backend sync', () => {
|
describe('backend sync', () => {
|
||||||
|
@ -37,7 +37,7 @@ import { Menu } from 'src/components/Menu';
|
|||||||
import Icons from 'src/components/Icons';
|
import Icons from 'src/components/Icons';
|
||||||
import { detectOS } from 'src/utils/common';
|
import { detectOS } from 'src/utils/common';
|
||||||
import {
|
import {
|
||||||
addQueryEditor,
|
addNewQueryEditor,
|
||||||
CtasEnum,
|
CtasEnum,
|
||||||
estimateQueryCost,
|
estimateQueryCost,
|
||||||
persistEditorHeight,
|
persistEditorHeight,
|
||||||
@ -84,7 +84,6 @@ import ShareSqlLabQuery from '../ShareSqlLabQuery';
|
|||||||
import SqlEditorLeftBar from '../SqlEditorLeftBar';
|
import SqlEditorLeftBar from '../SqlEditorLeftBar';
|
||||||
import AceEditorWrapper from '../AceEditorWrapper';
|
import AceEditorWrapper from '../AceEditorWrapper';
|
||||||
import RunQueryActionButton from '../RunQueryActionButton';
|
import RunQueryActionButton from '../RunQueryActionButton';
|
||||||
import { newQueryTabName } from '../../utils/newQueryTabName';
|
|
||||||
import QueryLimitSelect from '../QueryLimitSelect';
|
import QueryLimitSelect from '../QueryLimitSelect';
|
||||||
|
|
||||||
const appContainer = document.getElementById('app');
|
const appContainer = document.getElementById('app');
|
||||||
@ -179,8 +178,6 @@ const SqlEditor = ({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const queryEditors = useSelector(({ sqlLab }) => sqlLab.queryEditors);
|
|
||||||
|
|
||||||
const [height, setHeight] = useState(0);
|
const [height, setHeight] = useState(0);
|
||||||
const [autorun, setAutorun] = useState(queryEditor.autorun);
|
const [autorun, setAutorun] = useState(queryEditor.autorun);
|
||||||
const [ctas, setCtas] = useState('');
|
const [ctas, setCtas] = useState('');
|
||||||
@ -274,13 +271,7 @@ const SqlEditor = ({
|
|||||||
key: userOS === 'Windows' ? 'ctrl+q' : 'ctrl+t',
|
key: userOS === 'Windows' ? 'ctrl+q' : 'ctrl+t',
|
||||||
descr: t('New tab'),
|
descr: t('New tab'),
|
||||||
func: () => {
|
func: () => {
|
||||||
const name = newQueryTabName(queryEditors || []);
|
dispatch(addNewQueryEditor(queryEditor));
|
||||||
dispatch(
|
|
||||||
addQueryEditor({
|
|
||||||
...queryEditor,
|
|
||||||
name,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@ import thunk from 'redux-thunk';
|
|||||||
import URI from 'urijs';
|
import URI from 'urijs';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallow, mount } from 'enzyme';
|
||||||
|
import { fireEvent, render, waitFor } from 'spec/helpers/testing-library';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock from 'fetch-mock';
|
||||||
@ -101,6 +102,11 @@ describe('TabbedSqlEditors', () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
const setup = (props = {}, overridesStore) =>
|
||||||
|
render(<TabbedSqlEditors {...props} />, {
|
||||||
|
useRedux: true,
|
||||||
|
store: overridesStore || store,
|
||||||
|
});
|
||||||
|
|
||||||
let wrapper;
|
let wrapper;
|
||||||
it('is valid', () => {
|
it('is valid', () => {
|
||||||
@ -163,23 +169,32 @@ describe('TabbedSqlEditors', () => {
|
|||||||
wrapper.instance().props.actions.removeQueryEditor.getCall(0).args[0],
|
wrapper.instance().props.actions.removeQueryEditor.getCall(0).args[0],
|
||||||
).toBe(queryEditors[0]);
|
).toBe(queryEditors[0]);
|
||||||
});
|
});
|
||||||
it('should add new query editor', () => {
|
it('should add new query editor', async () => {
|
||||||
wrapper = getWrapper();
|
const { getAllByLabelText } = setup(mockedProps);
|
||||||
sinon.stub(wrapper.instance().props.actions, 'addQueryEditor');
|
fireEvent.click(getAllByLabelText('Add tab')[0]);
|
||||||
|
const actions = store.getActions();
|
||||||
wrapper.instance().newQueryEditor();
|
await waitFor(() =>
|
||||||
expect(
|
expect(actions).toContainEqual({
|
||||||
wrapper.instance().props.actions.addQueryEditor.getCall(0).args[0].name,
|
type: 'ADD_QUERY_EDITOR',
|
||||||
).toContain('Untitled Query');
|
queryEditor: expect.objectContaining({
|
||||||
|
name: expect.stringMatching(/Untitled Query (\d+)+/),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should properly increment query tab name', () => {
|
it('should properly increment query tab name', async () => {
|
||||||
wrapper = getWrapper();
|
const { getAllByLabelText } = setup(mockedProps);
|
||||||
sinon.stub(wrapper.instance().props.actions, 'addQueryEditor');
|
const newTitle = newQueryTabName(store.getState().sqlLab.queryEditors);
|
||||||
const newTitle = newQueryTabName(wrapper.instance().props.queryEditors);
|
fireEvent.click(getAllByLabelText('Add tab')[0]);
|
||||||
wrapper.instance().newQueryEditor();
|
const actions = store.getActions();
|
||||||
expect(
|
await waitFor(() =>
|
||||||
wrapper.instance().props.actions.addQueryEditor.getCall(0).args[0].name,
|
expect(actions).toContainEqual({
|
||||||
).toContain(newTitle);
|
type: 'ADD_QUERY_EDITOR',
|
||||||
|
queryEditor: expect.objectContaining({
|
||||||
|
name: newTitle,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should duplicate query editor', () => {
|
it('should duplicate query editor', () => {
|
||||||
wrapper = getWrapper();
|
wrapper = getWrapper();
|
||||||
|
@ -29,7 +29,6 @@ import { Tooltip } from 'src/components/Tooltip';
|
|||||||
import { detectOS } from 'src/utils/common';
|
import { detectOS } from 'src/utils/common';
|
||||||
import * as Actions from 'src/SqlLab/actions/sqlLab';
|
import * as Actions from 'src/SqlLab/actions/sqlLab';
|
||||||
import { EmptyStateBig } from 'src/components/EmptyState';
|
import { EmptyStateBig } from 'src/components/EmptyState';
|
||||||
import { newQueryTabName } from '../../utils/newQueryTabName';
|
|
||||||
import SqlEditor from '../SqlEditor';
|
import SqlEditor from '../SqlEditor';
|
||||||
import SqlEditorTabHeader from '../SqlEditorTabHeader';
|
import SqlEditorTabHeader from '../SqlEditorTabHeader';
|
||||||
|
|
||||||
@ -242,10 +241,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
|||||||
'-- Note: Unless you save your query, these tabs will NOT persist if you clear your cookies or change browsers.\n\n',
|
'-- Note: Unless you save your query, these tabs will NOT persist if you clear your cookies or change browsers.\n\n',
|
||||||
);
|
);
|
||||||
|
|
||||||
const newTitle = newQueryTabName(this.props.queryEditors || []);
|
|
||||||
|
|
||||||
const qe = {
|
const qe = {
|
||||||
name: newTitle,
|
|
||||||
dbId:
|
dbId:
|
||||||
activeQueryEditor && activeQueryEditor.dbId
|
activeQueryEditor && activeQueryEditor.dbId
|
||||||
? activeQueryEditor.dbId
|
? activeQueryEditor.dbId
|
||||||
@ -255,7 +251,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
|||||||
sql: `${warning}SELECT ...`,
|
sql: `${warning}SELECT ...`,
|
||||||
queryLimit: this.props.defaultQueryLimit,
|
queryLimit: this.props.defaultQueryLimit,
|
||||||
};
|
};
|
||||||
this.props.actions.addQueryEditor(qe);
|
this.props.actions.addNewQueryEditor(qe);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSelect(key) {
|
handleSelect(key) {
|
||||||
|
Loading…
Reference in New Issue
Block a user