Make query builder work in data section

pull/10616/head
Andrew Watkins 2016-11-01 15:32:06 -07:00 committed by Will Piers
parent e5f20565fd
commit d75525ec46
10 changed files with 103 additions and 124 deletions

View File

@ -101,7 +101,7 @@ const TagList = React.createClass({
onChooseTag={this.props.onChooseTag}
onGroupByTag={this.props.onGroupByTag}
/>
);
);
})}
</ul>
);

View File

@ -36,7 +36,17 @@ export default function queryConfigs(state = {}, action) {
});
}
case 'LOAD_KAPACITOR_QUERY': {
const {queryID, query} = action.payload;
const nextState = Object.assign({}, state, {
[queryID]: query,
});
return nextState;
}
case 'CREATE_PANEL':
case 'ADD_KAPACITOR_QUERY':
case 'ADD_QUERY': {
const {queryId} = action.payload;
const nextState = Object.assign({}, state, {

View File

@ -1,96 +1,25 @@
import defaultQueryConfig from 'src/utils/defaultQueryConfig';
import uuid from 'node-uuid';
export function fetchTask(taskID) {
// do some ajax
//
return {
type: 'K_LOAD_TASK',
payload: {
taskID,
task: {
query: defaultQueryConfig(''),
otherProperties: {},
export function fetchRule(ruleID) {
return (dispatch) => {
// do some ajax
const queryID = uuid.v4();
dispatch({
type: 'LOAD_RULE',
payload: {
ruleID,
rule: {
queryID,
otherProperties: {},
},
},
},
};
}
});
export function toggleField(taskId, fieldFunc) {
return {
type: 'K_TOGGLE_FIELD',
payload: {
queryId,
fieldFunc,
},
};
}
export function groupByTime(queryId, time) {
return {
type: 'K_GROUP_BY_TIME',
payload: {
queryId,
time,
},
};
}
export function applyFuncsToField(queryId, fieldFunc) {
return {
type: 'K_APPLY_FUNCS_TO_FIELD',
payload: {
queryId,
fieldFunc,
},
};
}
export function chooseTag(queryId, tag) {
return {
type: 'K_CHOOSE_TAG',
payload: {
queryId,
tag,
},
};
}
export function chooseNamespace(queryId, {database, retentionPolicy}) {
return {
type: 'K_CHOOSE_NAMESPACE',
payload: {
queryId,
database,
retentionPolicy,
},
};
}
export function chooseMeasurement(queryId, measurement) {
return {
type: 'K_CHOOSE_MEASUREMENT',
payload: {
queryId,
measurement,
},
};
}
export function groupByTag(queryId, tagKey) {
return {
type: 'K_GROUP_BY_TAG',
payload: {
queryId,
tagKey,
},
};
}
export function toggleTagAcceptance(queryId) {
return {
type: 'K_TOGGLE_TAG_ACCEPTANCE',
payload: {
queryId,
},
dispatch({
type: 'ADD_KAPACITOR_QUERY',
payload: {
queryId: queryID,
},
});
};
}

View File

@ -20,8 +20,20 @@ export const DataSection = React.createClass({
kapacitors: PropTypes.string.isRequired,
}).isRequired,
}),
query: PropTypes.shape({}).isRequired,
query: PropTypes.shape({
id: PropTypes.string.isRequired,
}).isRequired,
addFlashMessage: PropTypes.func,
actions: PropTypes.shape({
chooseNamespace: PropTypes.func.isRequired,
chooseMeasurement: PropTypes.func.isRequired,
applyFuncsToField: PropTypes.func.isRequired,
chooseTag: PropTypes.func.isRequired,
groupByTag: PropTypes.func.isRequired,
toggleField: PropTypes.func.isRequired,
groupByTime: PropTypes.func.isRequired,
toggleTagAcceptance: PropTypes.func.isRequired,
}).isRequired,
},
childContextTypes: {
@ -44,27 +56,39 @@ export const DataSection = React.createClass({
},
handleChooseNamespace(namespace) {
this.props.actions.chooseNamespace(this.props.query.id, namespace);
this.setState({activeTab: MEASUREMENTS_TAB});
},
handleChooseMeasurement(measurement) {
this.props.actions.chooseMeasurement(this.props.query.id, measurement);
this.setState({activeTab: FIELDS_TAB});
},
handleToggleField({field, funcs}) {
handleToggleField(field) {
this.props.actions.toggleField(this.props.query.id, field);
},
handleGroupByTime(time) {
this.props.actions.groupByTime(this.props.query.id, time);
},
handleApplyFuncsToField(fieldFunc) {
this.props.actions.applyFuncsToField(this.props.query.id, fieldFunc);
},
handleChooseTag(tag) {
this.props.actions.chooseTag(this.props.query.id, tag);
},
handleToggleTagAcceptance() {
this.props.actions.toggleTagAcceptance(this.props.query.id);
},
handleGroupByTag(tagKey) {
this.props.actions.groupByTag(this.props.query.id, tagKey);
},
handleClickTab(tab) {

View File

@ -1,11 +1,12 @@
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import DataSection from '../components/DataSection';
import defaultQueryConfig from 'src/utils/defaultQueryConfig';
import * as actionCreators from '../actions/view';
import {bindActionCreators} from 'redux'
import ValuesSection from '../components/ValuesSection';
import * as kapacitorActionCreators from '../actions/view';
import * as queryActionCreators from '../../chronograf/actions/view';
import {bindActionCreators} from 'redux';
const TASK_ID = 1; // switch to this.props.params.taskID
const RULE_ID = 1; // switch to this.props.params.taskID
export const KapacitorRulePage = React.createClass({
propTypes: {
@ -15,14 +16,26 @@ export const KapacitorRulePage = React.createClass({
}).isRequired,
}),
addFlashMessage: PropTypes.func,
tasks: PropTypes.shape({}).isRequired,
rules: PropTypes.shape({}).isRequired,
queryConfigs: PropTypes.shape({}).isRequired,
kapacitorActions: PropTypes.shape({
fetchRule: PropTypes.func.isRequired,
}).isRequired,
queryActions: PropTypes.shape({}).isRequired,
},
componentDidMount() {
this.props.actions.fetchTask(TASK_ID);
this.props.kapacitorActions.fetchRule(RULE_ID);
},
render() {
const rule = this.props.rules[Object.keys(this.props.rules)[0]]; // this.props.params.taskID
const query = rule && this.props.queryConfigs[rule.queryID];
if (!query) { // or somethin like that
return null; // or a spinner or somethin
}
return (
<div className="kapacitor-rule-page">
<div className="enterprise-header">
@ -35,12 +48,12 @@ export const KapacitorRulePage = React.createClass({
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
{this.renderDataSection()}
{this.renderDataSection(query)}
</div>
</div>
<div className="row">
<div className="col-md-12">
{this.renderValuesSection()}
{this.renderValuesSection(rule)}
</div>
</div>
<div className="row">
@ -58,21 +71,20 @@ export const KapacitorRulePage = React.createClass({
);
},
renderDataSection() {
const task = this.props.tasks[Object.keys(this.props.tasks)[0]]; // this.props.params.taskID
const query = (task && task.query) || defaultQueryConfig('');
renderDataSection(query) {
return (
<div className="kapacitor-rule-section">
<h3>Data</h3>
<DataSection source={this.props.source} query={query} />
<DataSection source={this.props.source} query={query} actions={this.props.queryActions} />
</div>
);
},
renderValuesSection() {
renderValuesSection(rule) {
return (
<div className="kapacitor-rule-section">
<h3>Values</h3>
<ValuesSection rule={rule} />
</div>
);
},
@ -102,12 +114,16 @@ export const KapacitorRulePage = React.createClass({
function mapStateToProps(state) {
return {
tasks: state.tasks
rules: state.rules,
queryConfigs: state.queryConfigs,
};
}
function mapDispatchToProps(dispatch) {
return {actions: bindActionCreators(actionCreators, dispatch)}
return {
kapacitorActions: bindActionCreators(kapacitorActionCreators, dispatch),
queryActions: bindActionCreators(queryActionCreators, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(KapacitorRulePage);

View File

@ -0,0 +1,11 @@
export default function rules(state = {}, action) {
switch (action.type) {
case 'LOAD_RULE': {
const {ruleID, rule} = action.payload;
return Object.assign({}, state, {
[ruleID]: rule,
});
}
}
return state;
}

View File

@ -1,11 +0,0 @@
export default function tasks(state = {}, action) {
switch (action.type) {
case 'LOAD_TASK': {
const {taskID, task} = action.payload;
return Object.assign({}, state, {
[taskID]: task,
});
}
}
return state;
}

View File

@ -61,7 +61,7 @@ const UsersTable = React.createClass({
{this.renderDeleteButton(user)}
</td>
</tr>
);
);
})
}
</tbody>

View File

@ -76,7 +76,7 @@ export const ManageSources = React.createClass({
<td><Link className="btn btn-default btn-xs" to={`${pathname}/${source.id}/edit`}>Edit</Link></td>
<td><Link className="btn btn-success btn-xs" to={`/sources/${source.id}/hosts`}>Connect</Link></td>
</tr>
);
);
})
}
</tbody>

View File

@ -3,11 +3,11 @@ import {combineReducers} from 'redux';
import thunkMiddleware from 'redux-thunk';
import makeQueryExecuter from 'src/shared/middleware/queryExecuter';
import * as chronografReducers from 'src/chronograf/reducers';
import tasksReducer from 'src/kapacitor/reducers/tasks';
import rulesReducer from 'src/kapacitor/reducers/rules';
import notifications from 'src/shared/reducers/notifications';
import persistStateEnhancer from './persistStateEnhancer';
const rootReducer = combineReducers({notifications, ...chronografReducers, tasks: tasksReducer});
const rootReducer = combineReducers({notifications, ...chronografReducers, rules: rulesReducer});
export default function configureStore(initialState) {
const createPersistentStore = compose(