Skip to content

Commit

Permalink
Created store and reducers (#1108)
Browse files Browse the repository at this point in the history
* Created store and reducers

* Added spec

* Modifications based on comments
  • Loading branch information
vera-liu authored Sep 21, 2016
1 parent 8798fe6 commit dcfb604
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 103 deletions.
10 changes: 2 additions & 8 deletions caravel/assets/javascripts/SqlLab/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@ import TabbedSqlEditors from './components/TabbedSqlEditors';
import QueryAutoRefresh from './components/QueryAutoRefresh';
import Alerts from './components/Alerts';

import { bindActionCreators, compose, createStore } from 'redux';
import { bindActionCreators, createStore } from 'redux';
import { connect, Provider } from 'react-redux';

import { initialState, sqlLabReducer } from './reducers';
import persistState from 'redux-localstorage';
import { enhancer } from '../../utils/common';

require('./main.css');

let enhancer = compose(persistState());
if (process.env.NODE_ENV === 'dev') {
enhancer = compose(
persistState(), window.devToolsExtension && window.devToolsExtension()
);
}
let store = createStore(sqlLabReducer, initialState, enhancer);

// jquery hack to highlight the navbar menu
Expand Down
61 changes: 7 additions & 54 deletions caravel/assets/javascripts/SqlLab/reducers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import shortid from 'shortid';
import * as actions from './actions';
import { now } from '../modules/dates';
import
{ addToArr, alterInArr, removeFromArr, addToObject, alterInObject }
from '../../utils/reducerUtils';

const defaultQueryEditor = {
id: shortid.generate(),
Expand All @@ -23,58 +26,6 @@ export const initialState = {
queriesLastUpdate: 0,
};

function addToObject(state, arrKey, obj) {
const newObject = Object.assign({}, state[arrKey]);
const copiedObject = Object.assign({}, obj);

if (!copiedObject.id) {
copiedObject.id = shortid.generate();
}
newObject[copiedObject.id] = copiedObject;
return Object.assign({}, state, { [arrKey]: newObject });
}

function alterInObject(state, arrKey, obj, alterations) {
const newObject = Object.assign({}, state[arrKey]);
newObject[obj.id] = (Object.assign({}, newObject[obj.id], alterations));
return Object.assign({}, state, { [arrKey]: newObject });
}

function alterInArr(state, arrKey, obj, alterations) {
// Finds an item in an array in the state and replaces it with a
// new object with an altered property
const idKey = 'id';
const newArr = [];
state[arrKey].forEach((arrItem) => {
if (obj[idKey] === arrItem[idKey]) {
newArr.push(Object.assign({}, arrItem, alterations));
} else {
newArr.push(arrItem);
}
});
return Object.assign({}, state, { [arrKey]: newArr });
}

function removeFromArr(state, arrKey, obj, idKey = 'id') {
const newArr = [];
state[arrKey].forEach((arrItem) => {
if (!(obj[idKey] === arrItem[idKey])) {
newArr.push(arrItem);
}
});
return Object.assign({}, state, { [arrKey]: newArr });
}

function addToArr(state, arrKey, obj) {
const newObj = Object.assign({}, obj);
if (!newObj.id) {
newObj.id = shortid.generate();
}
const newState = {};
newState[arrKey] = [...state[arrKey], newObj];
return Object.assign({}, state, newState);
}

export const sqlLabReducer = function (state, action) {
const actionHandlers = {
[actions.ADD_QUERY_EDITOR]() {
Expand Down Expand Up @@ -115,7 +66,8 @@ export const sqlLabReducer = function (state, action) {
[actions.START_QUERY]() {
const newState = addToObject(state, 'queries', action.query);
const sqlEditor = { id: action.query.sqlEditorId };
return alterInArr(newState, 'queryEditors', sqlEditor, { latestQueryId: action.query.id });
return alterInArr(
newState, 'queryEditors', sqlEditor, { latestQueryId: action.query.id });
},
[actions.STOP_QUERY]() {
return alterInObject(state, 'queries', action.query, { state: 'stopped' });
Expand Down Expand Up @@ -156,7 +108,8 @@ export const sqlLabReducer = function (state, action) {
return alterInArr(state, 'queryEditors', action.queryEditor, { sql: action.sql });
},
[actions.QUERY_EDITOR_SET_AUTORUN]() {
return alterInArr(state, 'queryEditors', action.queryEditor, { autorun: action.autorun });
return alterInArr(
state, 'queryEditors', action.queryEditor, { autorun: action.autorun });
},
[actions.ADD_WORKSPACE_QUERY]() {
return addToArr(state, 'workspaceQueries', action.query);
Expand Down
71 changes: 71 additions & 0 deletions caravel/assets/javascripts/explorev2/actions/exploreActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
export const SET_DATASOURCE = 'SET_DATASOURCE';
export const SET_VIZTYPE = 'SET_VIZTYPE';
export const SET_TIME_FILTER = 'SET_TIME_FILTER';
export const SET_GROUPBY = 'SET_GROUPBY';
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_SQL = 'SET_SQL';
export const ADD_FILTER = 'ADD_FILTER';
export const SET_FILTER = 'SET_FILTER';
export const REMOVE_FILTER = 'REMOVE_FILTER';

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

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

export function setTimeFilter(timeFilter) {
return { type: SET_TIME_FILTER, timeFilter };
}

export function setGroupBy(groupBy) {
return { type: SET_GROUPBY, groupBy };
}

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 setSQL(sql) {
return { type: SET_SQL, sql };
}

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

export function removeFilter(filter) {
return { type: REMOVE_FILTER, filter };
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from 'react';
import { Panel } from 'react-bootstrap';

export default class ChartContainer extends React.Component {
render() {
return (
<Panel header="Chart title">
chart goes here
</Panel>
);
}
}
const ChartContainer = function () {
return (
<Panel header="Chart title">
chart goes here
</Panel>
);
};
export default ChartContainer;
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from 'react';
import { Panel } from 'react-bootstrap';

export default class ControlPanelsContainer extends React.Component {
render() {
return (
<Panel>
control panels here
</Panel>
);
}
}
const ControlPanelsContainer = function () {
return (
<Panel>
control panels here
</Panel>
);
};
export default ControlPanelsContainer;
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ import ChartContainer from './ChartContainer';
import ControlPanelsContainer from './ControlPanelsContainer';
import QueryAndSaveButtons from './QueryAndSaveButtons';

export default class ExploreViewContainer extends React.Component {
render() {
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>
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;
22 changes: 19 additions & 3 deletions caravel/assets/javascripts/explorev2/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ import React from 'react';
import ReactDOM from 'react-dom';
import ExploreViewContainer from './components/ExploreViewContainer';

import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { enhancer } from '../../utils/common';

import { initialState } from './stores/store';

const exploreViewContainer = document.getElementById('js-explore-view-container');
const bootstrapData = exploreViewContainer.getAttribute('data-bootstrap');

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

const bootstrappedState = Object.assign(initialState, {
datasources: bootstrapData.datasources,
viz: bootstrapData.viz,
});
const store = createStore(exploreReducer, bootstrappedState, enhancer);

ReactDOM.render(
<ExploreViewContainer
data={bootstrapData}
/>,
<Provider store={store}>
<ExploreViewContainer
data={bootstrapData}
/>
</Provider>,
exploreViewContainer
);
65 changes: 65 additions & 0 deletions caravel/assets/javascripts/explorev2/reducers/exploreReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as actions from '../actions/exploreActions';
import { addToArr, removeFromArr } from '../../../utils/reducerUtils';

export const exploreReducer = function (state, action) {
const actionHandlers = {
[actions.SET_DATASOURCE]() {
return Object.assign({}, state, { datasourceId: action.datasourceId });
},
[actions.SET_VIZTYPE]() {
return Object.assign({}, state, { vizType: action.vizType });
},
[actions.SET_TIME_FILTER]() {
return Object.assign({}, state, { timeFilter: action.timeFilter });
},
[actions.SET_GROUPBY]() {
return Object.assign({}, state, { groupBy: action.groupBy });
},
[actions.ADD_COLUMN]() {
return Object.assign({}, state, { columns: [...state.columns, action.column] });
},
[actions.REMOVE_COLUMN]() {
const newColumns = [];
state.columns.forEach((c) => {
if (c !== action.column) {
newColumns.push(c);
}
});
return Object.assign({}, state, { columns: newColumns });
},
[actions.ADD_ORDERING]() {
return Object.assign({}, state, { orderings: [...state.orderings, action.ordering] });
},
[actions.REMOVE_ORDERING]() {
const newOrderings = [];
state.orderings.forEach((o) => {
if (o !== action.ordering) {
newOrderings.push(o);
}
});
return Object.assign({}, state, { orderings: newOrderings });
},
[actions.SET_TIME_STAMP]() {
return Object.assign({}, state, { timeStampFormat: action.timeStampFormat });
},
[actions.SET_ROW_LIMIT]() {
return Object.assign({}, state, { rowLimit: action.rowLimit });
},
[actions.TOGGLE_SEARCHBOX]() {
return Object.assign({}, state, { searchBox: action.searchBox });
},
[actions.SET_SQL]() {
return Object.assign({}, state, { SQL: action.sql });
},
[actions.ADD_FILTER]() {
return addToArr(state, 'filters', action.filter);
},
[actions.REMOVE_FILTER]() {
return removeFromArr(state, 'filters', action.filter);
},
};
if (action.type in actionHandlers) {
return actionHandlers[action.type]();
}
return state;
};
Loading

0 comments on commit dcfb604

Please sign in to comment.