WIP adding funcs and fields to query config v2

pull/10616/head
Andrew Watkins 2017-10-10 16:46:56 -07:00
parent 1be7dbbd18
commit ac126541b8
2 changed files with 130 additions and 73 deletions

View File

@ -77,6 +77,7 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
})
)
const three = reducer(two, chooseMeasurement(queryId, 'disk'))
state = reducer(
three,
toggleField(queryId, {
@ -131,39 +132,38 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
const newState = reducer(
state,
toggleField(queryId, {field: 'a different field', funcs: []})
)
expect(newState[queryId].fields.length).to.equal(2)
expect(newState[queryId].fields[1].field).to.equal('a different field')
})
it('applies a funcs to newly selected fields', () => {
expect(state[queryId].fields.length).to.equal(1)
const oneFieldOneFunc = reducer(
state,
applyFuncsToField(queryId, {
name: 'func1',
alias: 'func1_field1',
args: ['field1'],
type: 'func',
})
)
const newState = reducer(
oneFieldOneFunc,
toggleField(queryId, {
name: 'f2',
alias: null,
args: [],
type: 'field',
})
)
expect(newState[queryId].fields[1].name).to.equal('func1')
expect(newState[queryId].fields[1].alias).to.equal('func1_f2')
expect(newState[queryId].fields[1].args).to.deep.equal(['f2'])
expect(newState[queryId].fields.length).to.equal(2)
expect(newState[queryId].fields[1].alias).to.deep.equal('mean_f2')
expect(newState[queryId].fields[1].args).to.deep.equal([
{name: 'f2', type: 'field'},
])
expect(newState[queryId].fields[1].name).to.deep.equal('mean')
})
it('applies a func to newly selected fields', () => {
expect(state[queryId].fields.length).to.equal(1)
expect(state[queryId].fields[0].type).to.equal('func')
expect(state[queryId].fields[0].name).to.equal('mean')
const newState = reducer(
state,
toggleField(queryId, {
name: 'f2',
type: 'field',
})
)
expect(newState[queryId].fields[1].name).to.equal('mean')
expect(newState[queryId].fields[1].alias).to.equal('mean_f2')
expect(newState[queryId].fields[1].args).to.deep.equal([
{name: 'f2', type: 'field'},
])
expect(newState[queryId].fields[1].type).to.equal('func')
})
@ -174,38 +174,53 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
const field = 'fk1'
const newState = reducer(
state,
toggleField(queryId, {field: 'fk1', funcs: []})
toggleField(queryId, {name: 'fk1', type: 'field'})
)
expect(newState[queryId].fields.length).to.equal(1)
expect(newState[queryId].fields[0].field).to.equal(field)
expect(newState[queryId].fields[0].alias).to.equal('mean_fk1')
expect(newState[queryId].fields[0].args).to.deep.equal([
{name: 'fk1', type: 'field'},
])
})
})
})
describe('DE_APPLY_FUNCS_TO_FIELD', () => {
it('applies functions to a field without any existing functions', () => {
describe.only('DE_APPLY_FUNCS_TO_FIELD', () => {
it('applies new functions to a field', () => {
const f1 = {name: 'f1', type: 'field'}
const f2 = {name: 'f2', type: 'field'}
const f3 = {name: 'f3', type: 'field'}
const f4 = {name: 'f4', type: 'field'}
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn1']},
{name: 'fn1', type: 'func', args: [f1], alias: `fn1_${f1.name}`},
{name: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.name}`},
{name: 'fn2', type: 'func', args: [f1], alias: `fn2_${f1.name}`},
],
},
}
const action = applyFuncsToField(queryId, {
field: 'f1',
funcs: ['fn3', 'fn4'],
field: {name: 'f1', type: 'field'},
funcs: [
{name: 'fn3', type: 'func', args: []},
{name: 'fn4', type: 'func', args: []},
],
})
const nextState = reducer(initialState, action)
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: ['fn3', 'fn4']},
{field: 'f2', funcs: ['fn1']},
console.log('foo: ', JSON.stringify(nextState[queryId].fields, null, 2))
expect(nextState[queryId].fields).to.deep.equal([
{name: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.name}`},
{name: 'fn3', type: 'func', args: [f1], alias: `fn3_${f1.name}`},
{name: 'fn4', type: 'func', args: [f1], alias: `fn4_${f1.name}`},
])
})

View File

@ -23,57 +23,80 @@ export const chooseMeasurement = (
measurement,
})
export const toggleField = (
query,
{name, alias, args, type},
isKapacitorRule = false
) => {
export const toggleField = (query, {name, type}, isKapacitorRule = false) => {
const {fields, groupBy} = query
if (!fields && !fields.length) {
if (!fields || !fields.length) {
return {
...query,
fields: [
{type: 'func', alias: `mean_${name}`, args: [name], name: 'mean'},
{
type: 'func',
alias: `mean_${name}`,
args: [{name, type: 'field'}],
name: 'mean',
},
],
}
}
const isSelected = fields.find(f => f.field === field)
if (isSelected) {
const nextFields = fields.filter(f => f.field !== field)
if (!nextFields.length) {
return {
...query,
fields: nextFields,
groupBy: {...groupBy, time: null},
}
}
const newFuncs = fields.filter(f => f.type === 'func')
if (!newFuncs) {
return {
...query,
fields: nextFields,
fields: [
...fields,
{
type: 'func',
alias: `mean_${name}`,
args: [{name, type: 'field'}],
name: 'mean',
},
],
}
}
if (isKapacitorRule) {
const newField = newFuncs.map(func => {
return {
...query,
fields: [{field, funcs}],
name: func.name,
type: 'func',
alias: `${func.name}_${name}`,
args: [{name, type}],
}
}
})
// const isSelected = fields.find(f => f.field === field)
// if (isSelected) {
// const nextFields = fields.filter(f => f.field !== field)
// if (!nextFields.length) {
// return {
// ...query,
// fields: nextFields,
// groupBy: {...groupBy, time: null},
// }
// }
let newFuncs = ['mean']
if (query.fields.length) {
newFuncs = query.fields.find(f => f.funcs).funcs
}
// return {
// ...query,
// fields: nextFields,
// }
// }
// if (isKapacitorRule) {
// return {
// ...query,
// fields: [{field, funcs}],
// }
// }
// let newFuncs = ['mean']
// if (query.fields.length) {
// newFuncs = query.fields.find(f => f.funcs).funcs
// }
return {
...query,
fields: query.fields.concat({
field,
funcs: newFuncs,
}),
fields: [...fields, ...newField],
}
}
@ -109,21 +132,40 @@ export function applyFuncsToField(
{field, funcs},
{preventAutoGroupBy = false, isKapacitorRule = false} = {}
) {
const shouldRemoveFuncs = funcs.length === 0
const nextFields = query.fields.map(f => {
const shouldRemoveFuncs = funcs && funcs.length === 0
let nextFields = query.fields.map(f => {
// If one field has no funcs, all fields must have no funcs
if (shouldRemoveFuncs) {
return Object.assign({}, f, {funcs: []})
return f.args.filter(a => a.type === 'field')
}
// If there is a func applied to only one field, add it to the other fields
if (f.field === field || !f.funcs || !f.funcs.length) {
return Object.assign({}, f, {funcs})
if (f.type === 'field') {
return funcs.map(func => {
return {
name: func.name,
type: func.type,
args: [{name: f.name, type: 'field'}],
alias: `${name}_${f.name}`,
}
})
}
return f
})
if (!shouldRemoveFuncs) {
nextFields = query.fields.filter(f =>
f.args.find(a => a.name !== field.name)
)
const modifiedFields = funcs.map(func => {
return {...func, args: [field], alias: `${func.name}_${field.name}`}
})
nextFields = [...nextFields, ...modifiedFields]
}
const defaultGroupBy = preventAutoGroupBy
? DEFAULT_DATA_EXPLORER_GROUP_BY_INTERVAL
: DEFAULT_DASHBOARD_GROUP_BY_INTERVAL