From 246b8d71be54edefb2350d48a9bcb25e25a2ee97 Mon Sep 17 00:00:00 2001 From: Timi Fasubaa Date: Mon, 1 Oct 2018 00:52:22 -0700 Subject: [PATCH 1/3] add timeout and refresh for failed backend --- superset/assets/src/SqlLab/actions.js | 6 +++++ .../SqlLab/components/QueryAutoRefresh.jsx | 23 ++++++++++++++++++- .../src/SqlLab/components/SouthPane.jsx | 1 + superset/assets/src/SqlLab/reducers.js | 6 +++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/superset/assets/src/SqlLab/actions.js b/superset/assets/src/SqlLab/actions.js index 8c9ef2d49e681..178a3af7c2fd1 100644 --- a/superset/assets/src/SqlLab/actions.js +++ b/superset/assets/src/SqlLab/actions.js @@ -34,6 +34,7 @@ export const SET_DATABASES = 'SET_DATABASES'; export const SET_ACTIVE_QUERY_EDITOR = 'SET_ACTIVE_QUERY_EDITOR'; export const SET_ACTIVE_SOUTHPANE_TAB = 'SET_ACTIVE_SOUTHPANE_TAB'; export const REFRESH_QUERIES = 'REFRESH_QUERIES'; +export const USER_OFFLINE = 'USER_OFFLINE'; export const RUN_QUERY = 'RUN_QUERY'; export const START_QUERY = 'START_QUERY'; export const STOP_QUERY = 'STOP_QUERY'; @@ -342,6 +343,11 @@ export function refreshQueries(alteredQueries) { return { type: REFRESH_QUERIES, alteredQueries }; } +export function userOffline() { + var res= {'offline': true} + return { type: USER_OFFLINE, res}; +} + export function persistEditorHeight(queryEditor, currentHeight) { return { type: QUERY_EDITOR_PERSIST_HEIGHT, queryEditor, currentHeight }; } diff --git a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx index 0b0936458362b..0b19de16c847a 100644 --- a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx +++ b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx @@ -41,16 +41,37 @@ class QueryAutoRefresh extends React.PureComponent { } stopwatch() { // only poll /superset/queries/ if there are started or running queries + const self = this; if (this.shouldCheckForQueries()) { SupersetClient.get({ endpoint: `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`, + timeout: '7000', }).then(({ json }) => { if (Object.keys(json).length > 0) { this.props.actions.refreshQueries(json); } - }); + }).catch((err) => { + console.log(err); + }); } } +/*======= + const url = `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`; + $.ajax({ + dataType: 'json', + url, + success: (data) => { + if (Object.keys(data).length > 0) { + self.props.actions.refreshQueries(data); + } + }, + error: (XMLHttpRequest) => { + if (XMLHttpRequest.readyState === 0) { + self.props.actions.userOffline(); + // document.location.reload(true); + } + }, +>>>>>>> add timeout and refresh for failed backend*/ render() { return null; } diff --git a/superset/assets/src/SqlLab/components/SouthPane.jsx b/superset/assets/src/SqlLab/components/SouthPane.jsx index 65d17f7768c52..70439eac4d5a7 100644 --- a/superset/assets/src/SqlLab/components/SouthPane.jsx +++ b/superset/assets/src/SqlLab/components/SouthPane.jsx @@ -103,6 +103,7 @@ function mapStateToProps({ sqlLab }) { return { activeSouthPaneTab: sqlLab.activeSouthPaneTab, databases: sqlLab.databases, + offline: offline, }; } diff --git a/superset/assets/src/SqlLab/reducers.js b/superset/assets/src/SqlLab/reducers.js index e357111ca824f..36d456414185f 100644 --- a/superset/assets/src/SqlLab/reducers.js +++ b/superset/assets/src/SqlLab/reducers.js @@ -250,6 +250,12 @@ export const sqlLabReducer = function (state = {}, action) { } return Object.assign({}, state, { queries: newQueries, queriesLastUpdate }); }, + [actions.USER_OFFLINE]() { + console.log(action) + console.log(state) + return Object.assign({}, state, {'offline':true}); + // set the values into the ? and it will propagate down... + }, [actions.CREATE_DATASOURCE_STARTED]() { return Object.assign({}, state, { isDatasourceLoading: true, From 94f572f26e07be7eabfb86b2b03f7f28299ae48f Mon Sep 17 00:00:00 2001 From: Timi Fasubaa Date: Wed, 3 Oct 2018 16:23:16 -0700 Subject: [PATCH 2/3] show offline state instead of refreshing --- .../sqllab/SqlEditorLeftBar_spec.jsx | 13 +++++++++++-- .../sqllab/TabbedSqlEditors_spec.jsx | 6 ++++++ superset/assets/src/SqlLab/actions.js | 7 +++---- .../SqlLab/components/QueryAutoRefresh.jsx | 8 ++++---- .../src/SqlLab/components/SouthPane.jsx | 13 +++++++++++-- .../SqlLab/components/SqlEditorLeftBar.jsx | 19 +++++++++++++++++-- .../SqlLab/components/TabbedSqlEditors.jsx | 4 ++++ superset/assets/src/SqlLab/constants.js | 3 +++ superset/assets/src/SqlLab/getInitialState.js | 4 +++- superset/assets/src/SqlLab/reducers.js | 5 +---- 10 files changed, 63 insertions(+), 19 deletions(-) diff --git a/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx b/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx index b233e19d42f89..4e2e1b94e2154 100644 --- a/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx @@ -1,9 +1,12 @@ import React from 'react'; +import configureStore from 'redux-mock-store'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import fetchMock from 'fetch-mock'; +import thunk from 'redux-thunk' -import { table, defaultQueryEditor, databases, tables } from './fixtures'; +import $ from 'jquery'; +import { table, defaultQueryEditor, databases, initialState, tables } from './fixtures'; import SqlEditorLeftBar from '../../../src/SqlLab/components/SqlEditorLeftBar'; import TableElement from '../../../src/SqlLab/components/TableElement'; @@ -21,11 +24,17 @@ describe('SqlEditorLeftBar', () => { database: {}, height: 0, }; + const middlewares = [thunk]; + const mockStore = configureStore(middlewares); + const store = mockStore(initialState); let wrapper; beforeEach(() => { - wrapper = shallow(); + ajaxStub = sinon.stub($, 'get'); + wrapper = shallow(, { + context: { store }, + }).dive(); }); it('is valid', () => { diff --git a/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx b/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx index 046e2a6ab56ec..803ca2d0bc5d9 100644 --- a/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx @@ -53,6 +53,7 @@ describe('TabbedSqlEditors', () => { getHeight: () => ('100px'), database: {}, }; + const getWrapper = () => ( shallow(, { context: { store }, @@ -166,4 +167,9 @@ describe('TabbedSqlEditors', () => { const lastTab = wrapper.find(Tab).last(); expect(lastTab.props().eventKey).toContain('add_tab'); }); + it('should disable new tab when offline', () => { + wrapper = getWrapper(); + wrapper.setProps( { offline: true }); + expect(wrapper.find(Tab).last().props().disabled).toBe(true); + }); }); diff --git a/superset/assets/src/SqlLab/actions.js b/superset/assets/src/SqlLab/actions.js index 178a3af7c2fd1..91e848649c664 100644 --- a/superset/assets/src/SqlLab/actions.js +++ b/superset/assets/src/SqlLab/actions.js @@ -34,7 +34,7 @@ export const SET_DATABASES = 'SET_DATABASES'; export const SET_ACTIVE_QUERY_EDITOR = 'SET_ACTIVE_QUERY_EDITOR'; export const SET_ACTIVE_SOUTHPANE_TAB = 'SET_ACTIVE_SOUTHPANE_TAB'; export const REFRESH_QUERIES = 'REFRESH_QUERIES'; -export const USER_OFFLINE = 'USER_OFFLINE'; +export const SET_USER_OFFLINE = 'SET_USER_OFFLINE'; export const RUN_QUERY = 'RUN_QUERY'; export const START_QUERY = 'START_QUERY'; export const STOP_QUERY = 'STOP_QUERY'; @@ -343,9 +343,8 @@ export function refreshQueries(alteredQueries) { return { type: REFRESH_QUERIES, alteredQueries }; } -export function userOffline() { - var res= {'offline': true} - return { type: USER_OFFLINE, res}; +export function setUserOffline(offline) { + return { type: SET_USER_OFFLINE, offline }; } export function persistEditorHeight(queryEditor, currentHeight) { diff --git a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx index 0b19de16c847a..ca1f682730c55 100644 --- a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx +++ b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx @@ -41,7 +41,6 @@ class QueryAutoRefresh extends React.PureComponent { } stopwatch() { // only poll /superset/queries/ if there are started or running queries - const self = this; if (this.shouldCheckForQueries()) { SupersetClient.get({ endpoint: `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`, @@ -59,16 +58,17 @@ class QueryAutoRefresh extends React.PureComponent { const url = `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`; $.ajax({ dataType: 'json', + timeout: 7000, url, success: (data) => { if (Object.keys(data).length > 0) { - self.props.actions.refreshQueries(data); + this.props.actions.refreshQueries(data); } + this.props.actions.setUserOffline(false); }, error: (XMLHttpRequest) => { if (XMLHttpRequest.readyState === 0) { - self.props.actions.userOffline(); - // document.location.reload(true); + this.props.actions.setUserOffline(true); } }, >>>>>>> add timeout and refresh for failed backend*/ diff --git a/superset/assets/src/SqlLab/components/SouthPane.jsx b/superset/assets/src/SqlLab/components/SouthPane.jsx index 70439eac4d5a7..c1e54b294218e 100644 --- a/superset/assets/src/SqlLab/components/SouthPane.jsx +++ b/superset/assets/src/SqlLab/components/SouthPane.jsx @@ -1,13 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import shortid from 'shortid'; -import { Alert, Tab, Tabs } from 'react-bootstrap'; +import { Alert, Label, Tab, Tabs } from 'react-bootstrap'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import * as Actions from '../actions'; import QueryHistory from './QueryHistory'; import ResultSet from './ResultSet'; +import { OFFLINE_STATE, STATE_BSSTYLE_MAP } from '../constants'; import { t } from '../../locales'; /* @@ -21,10 +22,12 @@ const propTypes = { activeSouthPaneTab: PropTypes.string, height: PropTypes.number, databases: PropTypes.object.isRequired, + offline: PropTypes.bool, }; const defaultProps = { activeSouthPaneTab: 'Results', + offline: false, }; class SouthPane extends React.PureComponent { @@ -32,6 +35,12 @@ class SouthPane extends React.PureComponent { this.props.actions.setActiveSouthPaneTab(id); } render() { + if (this.props.offline) { + return ( + ); + } const innerTabHeight = this.props.height - 55; let latestQuery; const props = this.props; @@ -103,7 +112,7 @@ function mapStateToProps({ sqlLab }) { return { activeSouthPaneTab: sqlLab.activeSouthPaneTab, databases: sqlLab.databases, - offline: offline, + offline: sqlLab.offline, }; } diff --git a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx index f17f8103ec57e..3b6a1e767b435 100644 --- a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx +++ b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { ControlLabel, Button } from 'react-bootstrap'; +import { connect } from 'react-redux'; import Select from 'react-virtualized-select'; import createFilterOptions from 'react-select-fast-filter-options'; import { SupersetClient } from '@superset-ui/core'; @@ -16,11 +17,13 @@ const propTypes = { tables: PropTypes.array, actions: PropTypes.object, database: PropTypes.object, + offline: PropTypes.bool, }; const defaultProps = { tables: [], actions: {}, + offline: false, }; class SqlEditorLeftBar extends React.PureComponent { @@ -50,7 +53,7 @@ class SqlEditorLeftBar extends React.PureComponent { } getTableNamesBySubStr(input) { - if (!this.props.queryEditor.dbId || !input) { + if (this.props.offline || !this.props.queryEditor.dbId || !input) { return Promise.resolve({ options: [] }); } @@ -76,6 +79,9 @@ class SqlEditorLeftBar extends React.PureComponent { fetchTables(dbId, schema, force, substr) { // This can be large so it shouldn't be put in the Redux store + if (this.props.offline) { + return; + } const forceRefresh = force || false; if (dbId && schema) { this.setState(() => ({ tableLoading: true, tableOptions: [] })); @@ -128,6 +134,9 @@ class SqlEditorLeftBar extends React.PureComponent { } fetchSchemas(dbId, force) { + if (this.props.offline) { + return; + } const actualDbId = dbId || this.props.queryEditor.dbId; const forceRefresh = force || false; if (actualDbId) { @@ -286,7 +295,13 @@ class SqlEditorLeftBar extends React.PureComponent { } } +function mapStateToProps({ sqlLab }) { + return { + offline: sqlLab.offline, + }; +} + SqlEditorLeftBar.propTypes = propTypes; SqlEditorLeftBar.defaultProps = defaultProps; -export default SqlEditorLeftBar; +export default connect(mapStateToProps)(SqlEditorLeftBar); diff --git a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx index cf94b5f5bb1f2..e693295aab374 100644 --- a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx @@ -21,9 +21,11 @@ const propTypes = { tabHistory: PropTypes.array.isRequired, tables: PropTypes.array.isRequired, getHeight: PropTypes.func.isRequired, + offline: PropTypes.bool, }; const defaultProps = { queryEditors: [], + offline: false, }; let queryCount = 1; @@ -234,6 +236,7 @@ class TabbedSqlEditors extends React.PureComponent { } eventKey="add_tab" + disabled={this.props.offline} /> ); @@ -250,6 +253,7 @@ function mapStateToProps({ sqlLab }) { tabHistory: sqlLab.tabHistory, tables: sqlLab.tables, defaultDbId: sqlLab.defaultDbId, + offline: sqlLab.offline, }; } function mapDispatchToProps(dispatch) { diff --git a/superset/assets/src/SqlLab/constants.js b/superset/assets/src/SqlLab/constants.js index 2a34112891844..633bb5be41b8c 100644 --- a/superset/assets/src/SqlLab/constants.js +++ b/superset/assets/src/SqlLab/constants.js @@ -1,4 +1,5 @@ export const STATE_BSSTYLE_MAP = { + offline: 'danger', failed: 'danger', pending: 'info', fetching: 'info', @@ -15,6 +16,8 @@ export const STATUS_OPTIONS = [ 'pending', ]; +export const OFFLINE_STATE = 'offline'; + export const TIME_OPTIONS = [ 'now', '1 hour ago', diff --git a/superset/assets/src/SqlLab/getInitialState.js b/superset/assets/src/SqlLab/getInitialState.js index 9c9210fb48668..8cd0f63c04f23 100644 --- a/superset/assets/src/SqlLab/getInitialState.js +++ b/superset/assets/src/SqlLab/getInitialState.js @@ -16,9 +16,11 @@ export default function getInitialState({ defaultDbId, ...restBootstrapData }) { return { featureFlags: restBootstrapData.common.feature_flags, sqlLab: { + activeSouthPaneTab: 'Results', alerts: [], - queries: {}, databases: {}, + offline: false, + queries: {}, queryEditors: [defaultQueryEditor], tabHistory: [defaultQueryEditor.id], tables: [], diff --git a/superset/assets/src/SqlLab/reducers.js b/superset/assets/src/SqlLab/reducers.js index 36d456414185f..b700a7a64a8d9 100644 --- a/superset/assets/src/SqlLab/reducers.js +++ b/superset/assets/src/SqlLab/reducers.js @@ -251,10 +251,7 @@ export const sqlLabReducer = function (state = {}, action) { return Object.assign({}, state, { queries: newQueries, queriesLastUpdate }); }, [actions.USER_OFFLINE]() { - console.log(action) - console.log(state) - return Object.assign({}, state, {'offline':true}); - // set the values into the ? and it will propagate down... + return Object.assign({}, state, { offline: action.offline }); }, [actions.CREATE_DATASOURCE_STARTED]() { return Object.assign({}, state, { From 573ebac5f69cb9cb82ab83f659f4c1cbb5693d1a Mon Sep 17 00:00:00 2001 From: Timi Fasubaa Date: Tue, 16 Oct 2018 16:26:06 -0700 Subject: [PATCH 3/3] add southpane tests --- .../javascripts/sqllab/SouthPane_spec.jsx | 37 +++++++++++++++++++ .../sqllab/SqlEditorLeftBar_spec.jsx | 4 +- .../sqllab/TabbedSqlEditors_spec.jsx | 4 +- .../SqlLab/components/QueryAutoRefresh.jsx | 26 +++---------- .../src/SqlLab/components/QuerySearch.jsx | 2 +- .../src/SqlLab/components/SouthPane.jsx | 6 +-- .../SqlLab/components/SqlEditorLeftBar.jsx | 10 +---- superset/assets/src/SqlLab/constants.js | 15 ++++---- superset/assets/src/SqlLab/getInitialState.js | 1 - superset/assets/src/SqlLab/reducers.js | 2 +- 10 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 superset/assets/spec/javascripts/sqllab/SouthPane_spec.jsx diff --git a/superset/assets/spec/javascripts/sqllab/SouthPane_spec.jsx b/superset/assets/spec/javascripts/sqllab/SouthPane_spec.jsx new file mode 100644 index 0000000000000..9836583b7346c --- /dev/null +++ b/superset/assets/spec/javascripts/sqllab/SouthPane_spec.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import configureStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; + +import { shallow } from 'enzyme'; + +import { STATUS_OPTIONS } from '../../../src/SqlLab/constants'; +import { initialState } from './fixtures'; +import SouthPane from '../../../src/SqlLab/components/SouthPane'; + +describe('SouthPane', () => { + const middlewares = [thunk]; + const mockStore = configureStore(middlewares); + const store = mockStore(initialState); + + const mockedProps = { + editorQueries: [], + dataPreviewQueries: [], + actions: {}, + activeSouthPaneTab: '', + height: 1, + databases: {}, + offline: false, + }; + + const getWrapper = () => ( + shallow(, { + context: { store }, + }).dive()); + + let wrapper; + it('should render offline when the state is offline', () => { + wrapper = getWrapper(); + wrapper.setProps({ offline: true }); + expect(wrapper.find('.m-r-3').render().text()).toBe(STATUS_OPTIONS.offline); + }); +}); diff --git a/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx b/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx index 4e2e1b94e2154..9d3c3f64a807d 100644 --- a/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/SqlEditorLeftBar_spec.jsx @@ -3,9 +3,8 @@ import configureStore from 'redux-mock-store'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import fetchMock from 'fetch-mock'; -import thunk from 'redux-thunk' +import thunk from 'redux-thunk'; -import $ from 'jquery'; import { table, defaultQueryEditor, databases, initialState, tables } from './fixtures'; import SqlEditorLeftBar from '../../../src/SqlLab/components/SqlEditorLeftBar'; import TableElement from '../../../src/SqlLab/components/TableElement'; @@ -31,7 +30,6 @@ describe('SqlEditorLeftBar', () => { let wrapper; beforeEach(() => { - ajaxStub = sinon.stub($, 'get'); wrapper = shallow(, { context: { store }, }).dive(); diff --git a/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx b/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx index 803ca2d0bc5d9..33d1e476af9c9 100644 --- a/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/TabbedSqlEditors_spec.jsx @@ -53,7 +53,6 @@ describe('TabbedSqlEditors', () => { getHeight: () => ('100px'), database: {}, }; - const getWrapper = () => ( shallow(, { context: { store }, @@ -169,7 +168,8 @@ describe('TabbedSqlEditors', () => { }); it('should disable new tab when offline', () => { wrapper = getWrapper(); - wrapper.setProps( { offline: true }); + expect(wrapper.find(Tab).last().props().disabled).toBe(false); + wrapper.setProps({ offline: true }); expect(wrapper.find(Tab).last().props().disabled).toBe(true); }); }); diff --git a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx index ca1f682730c55..ea6e780919faf 100644 --- a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx +++ b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx @@ -9,6 +9,7 @@ import * as Actions from '../actions'; const QUERY_UPDATE_FREQ = 2000; const QUERY_UPDATE_BUFFER_MS = 5000; const MAX_QUERY_AGE_TO_POLL = 21600000; +const QUERY_TIMEOUT_LIMIT = 7000; class QueryAutoRefresh extends React.PureComponent { componentWillMount() { @@ -44,34 +45,17 @@ class QueryAutoRefresh extends React.PureComponent { if (this.shouldCheckForQueries()) { SupersetClient.get({ endpoint: `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`, - timeout: '7000', + timeout: QUERY_TIMEOUT_LIMIT, }).then(({ json }) => { if (Object.keys(json).length > 0) { this.props.actions.refreshQueries(json); } - }).catch((err) => { - console.log(err); + this.props.actions.setUserOffline(false); + }).catch(() => { + this.props.actions.setUserOffline(true); }); } } -/*======= - const url = `/superset/queries/${this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS}`; - $.ajax({ - dataType: 'json', - timeout: 7000, - url, - success: (data) => { - if (Object.keys(data).length > 0) { - this.props.actions.refreshQueries(data); - } - this.props.actions.setUserOffline(false); - }, - error: (XMLHttpRequest) => { - if (XMLHttpRequest.readyState === 0) { - this.props.actions.setUserOffline(true); - } - }, ->>>>>>> add timeout and refresh for failed backend*/ render() { return null; } diff --git a/superset/assets/src/SqlLab/components/QuerySearch.jsx b/superset/assets/src/SqlLab/components/QuerySearch.jsx index a3d9ddf3a93c4..9e920295a0993 100644 --- a/superset/assets/src/SqlLab/components/QuerySearch.jsx +++ b/superset/assets/src/SqlLab/components/QuerySearch.jsx @@ -227,7 +227,7 @@ class QuerySearch extends React.PureComponent {