Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore control panel - Chart control, TimeFilter, GroupBy, Filters (… #1447

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions caravel/assets/javascripts/explorev2/actions/exploreActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
const $ = window.$ = require('jquery');
export const SET_DATASOURCE = 'SET_DATASOURCE';
export const SET_VIZTYPE = 'SET_VIZTYPE';
export const SET_TIME_COLUMN_OPTS = 'SET_TIME_COLUMN_OPTS';
export const SET_TIME_GRAIN_OPTS = 'SET_TIME_GRAIN_OPTS';
export const SET_TIME_COLUMN = 'SET_TIME_COLUMN';
export const SET_TIME_GRAIN = 'SET_TIME_GRAIN';
export const SET_SINCE = 'SET_SINCE';
export const SET_UNTIL = 'SET_UNTIL';
export const SET_GROUPBY_COLUMNS = 'SET_GROUPBY_COLUMNS';
export const SET_GROUPBY_COLUMN_OPTS = 'SET_GROUPBY_COLUMN_OPTS';
export const SET_METRICS = 'SET_METRICS';
export const SET_METRICS_OPTS = 'SET_METRICS_OPTS';
export const ADD_COLUMN = 'ADD_COLUMN';
export const REMOVE_COLUMN = 'REMOVE_COLUMN';
export const ADD_ORDERING = 'ADD_ORDERING';
export const REMOVE_ORDERING = 'REMOVE_ORDERING';
export const SET_TIME_STAMP = 'SET_TIME_STAMP';
export const SET_ROW_LIMIT = 'SET_ROW_LIMIT';
export const TOGGLE_SEARCHBOX = 'TOGGLE_SEARCHBOX';
export const SET_FILTER_COLUMN_OPTS = 'SET_FILTER_COLUMN_OPTS';
export const SET_WHERE_CLAUSE = 'SET_WHERE_CLAUSE';
export const SET_HAVING_CLAUSE = 'SET_HAVING_CLAUSE';
export const ADD_FILTER = 'ADD_FILTER';
export const SET_FILTER = 'SET_FILTER';
export const REMOVE_FILTER = 'REMOVE_FILTER';
export const CHANGE_FILTER_FIELD = 'CHANGE_FILTER_FIELD';
export const CHANGE_FILTER_OP = 'CHANGE_FILTER_OP';
export const CHANGE_FILTER_VALUE = 'CHANGE_FILTER_VALUE';
export const RESET_FORM_DATA = 'RESET_FORM_DATA';
export const CLEAR_ALL_OPTS = 'CLEAR_ALL_OPTS';

export function setTimeColumnOpts(timeColumnOpts) {
return { type: SET_TIME_COLUMN_OPTS, timeColumnOpts };
}

export function setTimeGrainOpts(timeGrainOpts) {
return { type: SET_TIME_GRAIN_OPTS, timeGrainOpts };
}

export function setGroupByColumnOpts(groupByColumnOpts) {
return { type: SET_GROUPBY_COLUMN_OPTS, groupByColumnOpts };
}

export function setMetricsOpts(metricsOpts) {
return { type: SET_METRICS_OPTS, metricsOpts };
}

export function setFilterColumnOpts(filterColumnOpts) {
return { type: SET_FILTER_COLUMN_OPTS, filterColumnOpts };
}

export function resetFormData() {
// Clear all form data when switching datasource
return { type: RESET_FORM_DATA };
}

export function clearAllOpts() {
return { type: CLEAR_ALL_OPTS };
}

export function setFormOpts(datasourceId, datasourceType) {
return function (dispatch) {
const timeColumnOpts = [];
const groupByColumnOpts = [];
const metricsOpts = [];
const filterColumnOpts = [];
const timeGrainOpts = [];

if (datasourceId) {
const params = [`datasource_id=${datasourceId}`, `datasource_type=${datasourceType}`];
const url = '/caravel/fetch_datasource_metadata?' + params.join('&');

$.get(url, (data, status) => {
if (status === 'success') {
data.dttm_cols.forEach((d) => {
if (d) timeColumnOpts.push({ value: d, label: d });
});
data.groupby_cols.forEach((d) => {
if (d) groupByColumnOpts.push({ value: d, label: d });
});
data.metrics.forEach((d) => {
if (d) metricsOpts.push({ value: d[1], label: d[0] });
});
data.filter_cols.forEach((d) => {
if (d) filterColumnOpts.push({ value: d, label: d });
});
data.time_grains.forEach((d) => {
if (d) timeGrainOpts.push({ value: d, label: d });
});
// Repopulate options for controls
dispatch(setTimeColumnOpts(timeColumnOpts));
dispatch(setTimeGrainOpts(timeGrainOpts));
dispatch(setGroupByColumnOpts(groupByColumnOpts));
dispatch(setMetricsOpts(metricsOpts));
dispatch(setFilterColumnOpts(filterColumnOpts));
}
});
} else {
// Clear all Select options
dispatch(clearAllOpts());
}
};
}

export function setDatasource(datasourceId) {
return { type: SET_DATASOURCE, datasourceId };
}

export function setVizType(vizType) {
return { type: SET_VIZTYPE, vizType };
}

export function setTimeColumn(timeColumn) {
return { type: SET_TIME_COLUMN, timeColumn };
}

export function setTimeGrain(timeGrain) {
return { type: SET_TIME_GRAIN, timeGrain };
}

export function setSince(since) {
return { type: SET_SINCE, since };
}

export function setUntil(until) {
return { type: SET_UNTIL, until };
}

export function setGroupByColumns(groupByColumns) {
return { type: SET_GROUPBY_COLUMNS, groupByColumns };
}

export function setMetrics(metrics) {
return { type: SET_METRICS, metrics };
}

export function addColumn(column) {
return { type: ADD_COLUMN, column };
}

export function removeColumn(column) {
return { type: REMOVE_COLUMN, column };
}

export function addOrdering(ordering) {
return { type: ADD_ORDERING, ordering };
}

export function removeOrdering(ordering) {
return { type: REMOVE_ORDERING, ordering };
}

export function setTimeStamp(timeStampFormat) {
return { type: SET_TIME_STAMP, timeStampFormat };
}

export function setRowLimit(rowLimit) {
return { type: SET_ROW_LIMIT, rowLimit };
}

export function toggleSearchBox(searchBox) {
return { type: TOGGLE_SEARCHBOX, searchBox };
}

export function setWhereClause(whereClause) {
return { type: SET_WHERE_CLAUSE, whereClause };
}

export function setHavingClause(havingClause) {
return { type: SET_HAVING_CLAUSE, havingClause };
}

export function addFilter(filter) {
return { type: ADD_FILTER, filter };
}

export function removeFilter(filter) {
return { type: REMOVE_FILTER, filter };
}

export function changeFilterField(filter, field) {
return { type: CHANGE_FILTER_FIELD, filter, field };
}

export function changeFilterOp(filter, op) {
return { type: CHANGE_FILTER_OP, filter, op };
}

export function changeFilterValue(filter, value) {
return { type: CHANGE_FILTER_VALUE, filter, value };
}
11 changes: 11 additions & 0 deletions caravel/assets/javascripts/explorev2/components/ChartContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { Panel } from 'react-bootstrap';

const ChartContainer = function () {
return (
<Panel header="Chart title">
chart goes here
</Panel>
);
};
export default ChartContainer;
89 changes: 89 additions & 0 deletions caravel/assets/javascripts/explorev2/components/ChartControl.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react';
import Select from 'react-select';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import { VIZ_TYPES } from '../constants';

const propTypes = {
actions: React.PropTypes.object,
datasources: React.PropTypes.array,
datasourceId: React.PropTypes.number,
datasourceType: React.PropTypes.string,
vizType: React.PropTypes.string,
};

const defaultProps = {
datasources: [],
datasourceId: null,
datasourceType: null,
vizType: null,
};

class ChartControl extends React.Component {
componentWillMount() {
if (this.props.datasourceId) {
this.props.actions.setFormOpts(this.props.datasourceId, this.props.datasourceType);
}
}
changeDatasource(datasourceOpt) {
const val = (datasourceOpt) ? datasourceOpt.value : null;
this.props.actions.setDatasource(val);
this.props.actions.resetFormData();
this.props.actions.setFormOpts(val, this.props.datasourceType);
}
changeViz(vizOpt) {
const val = (vizOpt) ? vizOpt.value : null;
this.props.actions.setVizType(val);
}
render() {
return (
<div className="panel space-1">
<div className="panel-header">Chart Options</div>
<div className="panel-body">
<h5 className="section-heading">Datasource</h5>
<div className="row">
<Select
name="select-datasource"
placeholder="Select a datasource"
options={this.props.datasources.map((d) => ({ value: d[0], label: d[1] }))}
value={this.props.datasourceId}
autosize={false}
onChange={this.changeDatasource.bind(this)}
/>
</div>
<h5 className="section-heading">Viz Type</h5>
<div className="row">
<Select
name="select-viztype"
placeholder="Select a viz type"
options={VIZ_TYPES}
value={this.props.vizType}
autosize={false}
onChange={this.changeViz.bind(this)}
/>
</div>
</div>
</div>
);
}
}

ChartControl.propTypes = propTypes;
ChartControl.defaultProps = defaultProps;

function mapStateToProps(state) {
return {
datasources: state.datasources,
datasourceId: state.datasourceId,
datasourceType: state.datasourceType,
vizType: state.vizType,
};
}

function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChartControl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { Panel } from 'react-bootstrap';
import TimeFilter from './TimeFilter';
import ChartControl from './ChartControl';
import GroupBy from './GroupBy';
import SqlClause from './SqlClause';
import Filters from './Filters';

const ControlPanelsContainer = function () {
return (
<Panel>
<ChartControl />
<TimeFilter />
<GroupBy />
<SqlClause />
<Filters />
</Panel>
);
};
export default ControlPanelsContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import ChartContainer from './ChartContainer';
import ControlPanelsContainer from './ControlPanelsContainer';
import QueryAndSaveButtons from './QueryAndSaveButtons';

const ExploreViewContainer = function () {
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-3">
<QueryAndSaveButtons
canAdd="True"
onQuery={() => { console.log('clicked query'); }}
/>
<br /><br />
<ControlPanelsContainer />
</div>
<div className="col-sm-9">
<ChartContainer />
</div>
</div>
</div>
);
};

export default ExploreViewContainer;
Loading