Skip to content

Commit

Permalink
Merge pull request apache#114 from kristw/kristw-cherry-sep18
Browse files Browse the repository at this point in the history
Cherry-picks: Several bug fixes and react HMR
  • Loading branch information
kristw committed Sep 18, 2018
2 parents 301f289 + 248a45d commit 901ea8a
Show file tree
Hide file tree
Showing 26 changed files with 385 additions and 332 deletions.
2 changes: 1 addition & 1 deletion superset/assets/.babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"presets" : ["airbnb", "react", "env"],
"plugins": ["syntax-dynamic-import"],
"plugins": ["syntax-dynamic-import", "react-hot-loader/babel"]
}
3 changes: 2 additions & 1 deletion superset/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"react-dnd-html5-backend": "^2.5.4",
"react-dom": "^15.6.2",
"react-gravatar": "^2.6.1",
"react-hot-loader": "^4.3.6",
"react-map-gl": "^3.0.4",
"react-markdown": "^3.3.0",
"react-redux": "^5.0.2",
Expand All @@ -113,7 +114,7 @@
"react-syntax-highlighter": "^5.7.0",
"react-virtualized": "9.3.0",
"react-virtualized-select": "2.4.0",
"reactable": "^0.14.1",
"reactable": "^1.1.0",
"redux": "^3.5.2",
"redux-localstorage": "^0.4.1",
"redux-thunk": "^2.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { shallow } from 'enzyme';
import { describe, it } from 'mocha';
import { expect } from 'chai';

import App from '../../../src/welcome/App';
import Welcome from '../../../src/welcome/Welcome';

describe('App', () => {
describe('Welcome', () => {
const mockedProps = {};
it('is valid', () => {
expect(
React.isValidElement(<App {...mockedProps} />),
React.isValidElement(<Welcome {...mockedProps} />),
).to.equal(true);
});
it('renders 4 Tab, Panel, and Row components', () => {
const wrapper = shallow(<App {...mockedProps} />);
const wrapper = shallow(<Welcome {...mockedProps} />);
expect(wrapper.find(Tab)).to.have.length(3);
expect(wrapper.find(Panel)).to.have.length(3);
expect(wrapper.find(Row)).to.have.length(3);
Expand Down
51 changes: 51 additions & 0 deletions superset/assets/src/SqlLab/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import { createStore, compose, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';
import { hot } from 'react-hot-loader';

import getInitialState from './getInitialState';
import rootReducer from './reducers';
import { initEnhancer } from '../reduxUtils';
import { initJQueryAjax } from '../modules/utils';
import App from './components/App';
import { appSetup } from '../common';

import './main.less';
import '../../stylesheets/reactable-pagination.css';
import '../components/FilterableTable/FilterableTableStyles.css';

appSetup();
initJQueryAjax();

const appContainer = document.getElementById('app');
const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
const state = getInitialState(bootstrapData);

const store = createStore(
rootReducer,
state,
compose(
applyMiddleware(thunkMiddleware),
initEnhancer(),
),
);

// Highlight the navbar menu
const menus = document.querySelectorAll('.nav.navbar-nav li.dropdown');
const sqlLabMenu = Array.prototype.slice.apply(menus)
.find(element => element.innerText.trim() === 'SQL Lab');
if (sqlLabMenu) {
const classes = sqlLabMenu.getAttribute('class');
if (classes.indexOf('active') === -1) {
sqlLabMenu.setAttribute('class', `${classes} active`);
}
}

const Application = () => (
<Provider store={store}>
<App />
</Provider>
);

export default hot(module)(Application);
46 changes: 5 additions & 41 deletions superset/assets/src/SqlLab/index.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,8 @@
import React from 'react';
import { render } from 'react-dom';
import { createStore, compose, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';
import ReactDOM from 'react-dom';
import App from './App';

import getInitialState from './getInitialState';
import rootReducer from './reducers';
import { initEnhancer } from '../reduxUtils';
import { initJQueryAjax } from '../modules/utils';
import App from './components/App';
import { appSetup } from '../common';

import './main.less';
import '../../stylesheets/reactable-pagination.css';
import '../components/FilterableTable/FilterableTableStyles.css';

appSetup();
initJQueryAjax();

const appContainer = document.getElementById('app');
const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
const state = getInitialState(bootstrapData);

const store = createStore(
rootReducer,
state,
compose(
applyMiddleware(thunkMiddleware),
initEnhancer(),
),
);

// jquery hack to highlight the navbar menu
$('a:contains("SQL Lab")')
.parent()
.addClass('active');

render(
<Provider store={store}>
<App />
</Provider>,
appContainer,
ReactDOM.render(
<App />,
document.getElementById('app'),
);
15 changes: 15 additions & 0 deletions superset/assets/src/addSlice/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { hot } from 'react-hot-loader';
import { appSetup } from '../common';
import AddSliceContainer from './AddSliceContainer';

appSetup();

const addSliceContainer = document.getElementById('js-add-slice-container');
const bootstrapData = JSON.parse(addSliceContainer.getAttribute('data-bootstrap'));

const App = () => (
<AddSliceContainer datasources={bootstrapData.datasources} />
);

export default hot(module)(App);
12 changes: 3 additions & 9 deletions superset/assets/src/addSlice/index.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { appSetup } from '../common';
import AddSliceContainer from './AddSliceContainer';

appSetup();

const addSliceContainer = document.getElementById('js-add-slice-container');
const bootstrapData = JSON.parse(addSliceContainer.getAttribute('data-bootstrap'));
import App from './App';

ReactDOM.render(
<AddSliceContainer datasources={bootstrapData.datasources} />,
addSliceContainer,
<App />,
document.getElementById('js-add-slice-container'),
);
36 changes: 36 additions & 0 deletions superset/assets/src/dashboard/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import { hot } from 'react-hot-loader';

import { initEnhancer } from '../reduxUtils';
import { appSetup } from '../common';
import { initJQueryAjax } from '../modules/utils';
import DashboardContainer from './containers/Dashboard';
import getInitialState from './reducers/getInitialState';
import rootReducer from './reducers/index';

appSetup();
initJQueryAjax();

const appContainer = document.getElementById('app');
const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
const initState = getInitialState(bootstrapData);

const store = createStore(
rootReducer,
initState,
compose(
applyMiddleware(thunk),
initEnhancer(false),
),
);

const App = () => (
<Provider store={store}>
<DashboardContainer />
</Provider>
);

export default hot(module)(App);
34 changes: 2 additions & 32 deletions superset/assets/src/dashboard/index.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import App from './App';

import { initEnhancer } from '../reduxUtils';
import { appSetup } from '../common';
import { initJQueryAjax } from '../modules/utils';
import DashboardContainer from './containers/Dashboard';
import getInitialState from './reducers/getInitialState';
import rootReducer from './reducers/index';

appSetup();
initJQueryAjax();

const appContainer = document.getElementById('app');
const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
const initState = getInitialState(bootstrapData);

const store = createStore(
rootReducer,
initState,
compose(
applyMiddleware(thunk),
initEnhancer(false),
),
);

ReactDOM.render(
<Provider store={store}>
<DashboardContainer />
</Provider>,
appContainer,
);
ReactDOM.render(<App />, document.getElementById('app'));
92 changes: 92 additions & 0 deletions superset/assets/src/explore/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* eslint no-undef: 2 */
import React from 'react';
import { hot } from 'react-hot-loader';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';

import shortid from 'shortid';
import { now } from '../modules/dates';
import { initEnhancer } from '../reduxUtils';
import { getChartKey } from './exploreUtils';
import ToastPresenter from '../messageToasts/containers/ToastPresenter';
import { getControlsState, getFormDataFromControls } from './store';
import { initJQueryAjax } from '../modules/utils';
import ExploreViewContainer from './components/ExploreViewContainer';
import rootReducer from './reducers/index';
import getToastsFromPyFlashMessages from '../messageToasts/utils/getToastsFromPyFlashMessages';

import { appSetup } from '../common';
import './main.css';
import '../../stylesheets/reactable-pagination.css';

appSetup();
initJQueryAjax();

const exploreViewContainer = document.getElementById('app');
const bootstrapData = JSON.parse(exploreViewContainer.getAttribute('data-bootstrap'));
const controls = getControlsState(bootstrapData, bootstrapData.form_data);
const rawFormData = { ...bootstrapData.form_data };

delete bootstrapData.form_data;
delete bootstrapData.common.locale;
delete bootstrapData.common.language_pack;

// Initial state
const bootstrappedState = {
...bootstrapData,
rawFormData,
controls,
filterColumnOpts: [],
isDatasourceMetaLoading: false,
isStarred: false,
};
const slice = bootstrappedState.slice;
const sliceFormData = slice
? getFormDataFromControls(getControlsState(bootstrapData, slice.form_data))
: null;
const chartKey = getChartKey(bootstrappedState);
const initState = {
charts: {
[chartKey]: {
id: chartKey,
chartAlert: null,
chartStatus: 'loading',
chartUpdateEndTime: null,
chartUpdateStartTime: now(),
latestQueryFormData: getFormDataFromControls(controls),
sliceFormData,
queryRequest: null,
queryResponse: null,
triggerQuery: true,
lastRendered: 0,
},
},
saveModal: {
dashboards: [],
saveModalAlert: null,
},
explore: bootstrappedState,
impressionId: shortid.generate(),
messageToasts: getToastsFromPyFlashMessages((bootstrapData.common || {}).flash_messages || []),
};

const store = createStore(
rootReducer,
initState,
compose(
applyMiddleware(thunk),
initEnhancer(false),
),
);

const App = () => (
<Provider store={store}>
<div>
<ExploreViewContainer />
<ToastPresenter />
</div>
</Provider>
);

export default hot(module)(App);
Loading

0 comments on commit 901ea8a

Please sign in to comment.