Skip to content

Commit

Permalink
Vliu put datasource in store (#1610)
Browse files Browse the repository at this point in the history
* Move datasource from global store object to form_data

* Moved datasource_id  and datasource_name to form_data

* Refetch defaultFormData when switching datasource

* Fixed js tests
  • Loading branch information
vera-liu authored Nov 17, 2016
1 parent ab5da5b commit 4f7f437
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint camelcase: 0 */
const $ = window.$ = require('jquery');

export const SET_FIELD_OPTIONS = 'SET_FIELD_OPTIONS';
export function setFieldOptions(options) {
return { type: SET_FIELD_OPTIONS, options };
Expand Down Expand Up @@ -75,8 +74,8 @@ export function changeFilterValue(filter, value) {
}

export const SET_FIELD_VALUE = 'SET_FIELD_VALUE';
export function setFieldValue(key, value) {
return { type: SET_FIELD_VALUE, key, value };
export function setFieldValue(key, value, label) {
return { type: SET_FIELD_VALUE, key, value, label };
}

export const UPDATE_CHART = 'UPDATE_CHART';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import ControlPanelSection from './ControlPanelSection';
import FieldSetRow from './FieldSetRow';

const propTypes = {
datasource_id: PropTypes.number.isRequired,
datasource_type: PropTypes.string.isRequired,
actions: PropTypes.object.isRequired,
fields: PropTypes.object.isRequired,
Expand All @@ -20,14 +19,24 @@ const propTypes = {

class ControlPanelsContainer extends React.Component {
componentWillMount() {
const { datasource_id, datasource_type } = this.props;
const datasource_id = this.props.form_data.datasource;
const datasource_type = this.props.datasource_type;
if (datasource_id) {
this.props.actions.fetchFieldOptions(datasource_id, datasource_type);
}
}

onChange(name, value) {
this.props.actions.setFieldValue(name, value);
componentWillReceiveProps(nextProps) {
if (nextProps.form_data.datasource !== this.props.form_data.datasource) {
if (nextProps.form_data.datasource) {
this.props.actions.fetchFieldOptions(
nextProps.form_data.datasource, nextProps.datasource_type);
}
}
}

onChange(name, value, label) {
this.props.actions.setFieldValue(name, value, label);
}

sectionsToRender() {
Expand Down Expand Up @@ -82,7 +91,6 @@ function mapStateToProps(state) {
return {
isDatasourceMetaLoading: state.isDatasourceMetaLoading,
fields: state.fields,
datasource_id: state.datasource_id,
datasource_type: state.datasource_type,
form_data: state.viz.form_data,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ const $ = require('jquery');
const propTypes = {
form_data: React.PropTypes.object.isRequired,
actions: React.PropTypes.object.isRequired,
slice_id: React.PropTypes.string.isRequired,
slice_name: React.PropTypes.string.isRequired,
datasource_id: React.PropTypes.number.isRequired,
datasource_type: React.PropTypes.string.isRequired,
};

Expand All @@ -31,14 +28,14 @@ class ExploreViewContainer extends React.Component {
const form_data = this.props.form_data;
Object.keys(form_data).forEach((field) => {
// filter out null fields
if (form_data[field] !== null) {
if (form_data[field] !== null && field !== 'datasource') {
data[field] = form_data[field];
}
});
// V2 tag temporarily for updating url
// Todo: remove after launch
data.V2 = true;
data.datasource_id = this.props.datasource_id;
data.datasource_id = this.props.form_data.datasource;
data.datasource_type = this.props.datasource_type;
this.queryFormData(data);

Expand All @@ -53,14 +50,14 @@ class ExploreViewContainer extends React.Component {

updateUrl(params) {
const baseUrl =
`/superset/explore/${this.props.datasource_type}/${this.props.datasource_id}/`;
`/superset/explore/${this.props.datasource_type}/${this.props.form_data.datasource}/`;
const newEndpoint = `${baseUrl}?${params}`;
history.pushState({}, document.title, newEndpoint);
}

queryFormData(data) {
this.props.actions.updateExplore(
this.props.datasource_type, this.props.datasource_id, data);
this.props.datasource_type, this.props.form_data.datasource, data);
}

render() {
Expand Down Expand Up @@ -99,11 +96,8 @@ ExploreViewContainer.propTypes = propTypes;

function mapStateToProps(state) {
return {
datasource_id: state.datasource_id,
datasource_type: state.datasource_type,
form_data: state.viz.form_data,
slice_id: state.viz.form_data.slice_id,
slice_name: state.viz.form_data.slice_name,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ export default class SelectField extends React.Component {
if (this.props.multi) {
optionValue = opt ? opt.map((o) => o.value) : null;
}
this.props.onChange(this.props.name, optionValue);
if (this.props.name === 'datasource' && optionValue !== null) {
this.props.onChange(this.props.name, optionValue, opt.label);
} else {
this.props.onChange(this.props.name, optionValue);
}
}
render() {
const options = this.props.choices.map((c) => ({ value: c[0], label: c[1] }));
Expand Down
5 changes: 3 additions & 2 deletions superset/assets/javascripts/explorev2/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ const bootstrapData = JSON.parse(exploreViewContainer.getAttribute('data-bootstr

import { exploreReducer } from './reducers/exploreReducer';

const bootstrappedState = Object.assign(initialState, {
const bootstrappedState = Object.assign(initialState(bootstrapData.viz.form_data.viz_type), {
can_download: bootstrapData.can_download,
datasources: bootstrapData.datasources,
datasource_id: parseInt(bootstrapData.datasource_id, 10),
datasource_type: bootstrapData.datasource_type,
viz: bootstrapData.viz,
});
bootstrappedState.viz.form_data.datasource = parseInt(bootstrapData.datasource_id, 10);
bootstrappedState.viz.form_data.datasource_name = bootstrapData.datasource_name;

const store = createStore(exploreReducer, bootstrappedState,
compose(applyMiddleware(thunk))
Expand Down
11 changes: 9 additions & 2 deletions superset/assets/javascripts/explorev2/reducers/exploreReducer.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { defaultFormData } from '../stores/store';
import * as actions from '../actions/exploreActions';
import { addToArr, removeFromArr, alterInArr } from '../../../utils/reducerUtils';

Expand Down Expand Up @@ -47,9 +48,15 @@ export const exploreReducer = function (state, action) {
return alterInArr(state, 'filters', action.filter, { value: action.value });
},
[actions.SET_FIELD_VALUE]() {
const newFormData = Object.assign({}, state.viz.form_data);
const newFormData = action.key === 'datasource' ?
defaultFormData(state.viz.form_data.viz_type) : Object.assign({}, state.viz.form_data);
if (action.key === 'datasource') {
newFormData.datasource_name = action.label;
newFormData.slice_id = state.viz.form_data.slice_id;
newFormData.slice_name = state.viz.form_data.slice_name;
newFormData.viz_type = state.viz.form_data.viz_type;
}
newFormData[action.key] = action.value ? action.value : (!state.viz.form_data[action.key]);

return Object.assign(
{},
state,
Expand Down
59 changes: 36 additions & 23 deletions superset/assets/javascripts/explorev2/stores/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -1628,34 +1628,47 @@ export const fields = {
},
};

export function defaultFormData() {
export function defaultFormData(vizType = 'table') {
const data = {
slice_name: null,
slice_id: null,
datasource_name: null,
};
Object.keys(fields).forEach((k) => { data[k] = fields[k].default; });
const { datasourceAndVizType, sqlClause } = commonControlPanelSections;
const viz = visTypes[vizType];
const sectionsToRender = [datasourceAndVizType].concat(viz.controlPanelSections, sqlClause);
sectionsToRender.forEach((section) => {
section.fieldSetRows.forEach((fieldSetRow) => {
fieldSetRow.forEach((k) => {
data[k] = fields[k].default;
});
});
});
return data;
}

export const defaultViz = {
cached_key: null,
cached_timeout: null,
cached_dttm: null,
column_formats: null,
csv_endpoint: null,
is_cached: false,
data: [],
form_data: defaultFormData(),
json_endpoint: null,
query: null,
standalone_endpoint: null,
};
export function defaultViz(vizType) {
return {
cached_key: null,
cached_timeout: null,
cached_dttm: null,
column_formats: null,
csv_endpoint: null,
is_cached: false,
data: [],
form_data: defaultFormData(vizType),
json_endpoint: null,
query: null,
standalone_endpoint: null,
};
}

export const initialState = {
isDatasourceMetaLoading: false,
datasources: null,
datasource_id: null,
datasource_type: null,
fields,
viz: defaultViz,
};
export function initialState(vizType = 'table') {
return {
isDatasourceMetaLoading: false,
datasources: null,
datasource_type: null,
fields,
viz: defaultViz(vizType),
};
}
5 changes: 3 additions & 2 deletions superset/assets/spec/javascripts/explorev2/actions_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { exploreReducer } from '../../../javascripts/explorev2/reducers/exploreR

describe('reducers', () => {
it('sets correct field value given a key and value', () => {
const newState = exploreReducer(initialState, actions.setFieldValue('x_axis_label', 'x'));
const newState = exploreReducer(
initialState('dist_bar'), actions.setFieldValue('x_axis_label', 'x'));
expect(newState.viz.form_data.x_axis_label).to.equal('x');
});
it('toggles a boolean field value given only a key', () => {
const newState = exploreReducer(initialState, actions.setFieldValue('show_legend'));
const newState = exploreReducer(initialState('dist_bar'), actions.setFieldValue('show_legend'));
expect(newState.viz.form_data.show_legend).to.equal(false);
});
});
1 change: 1 addition & 0 deletions superset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,7 @@ def explore(self, datasource_type, datasource_id):
# TODO: separate endpoint for fetching datasources
"datasources": [(d.id, d.full_name) for d in datasources],
"datasource_id": datasource_id,
"datasource_name": viz_obj.datasource.name,
"datasource_type": datasource_type,
"user_id": g.user.get_id() if g.user else None,
"viz": json.loads(viz_obj.get_json())
Expand Down

0 comments on commit 4f7f437

Please sign in to comment.