Update kapacitory query reducer

pull/2128/head
Andrew Watkins 2017-10-11 12:13:25 -07:00
parent 1cfe98ec09
commit 326a00b153
3 changed files with 55 additions and 61 deletions

View File

@ -65,7 +65,7 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
})
})
describe.only('a query has measurements and fields', () => {
describe('a query has measurements and fields', () => {
let state
beforeEach(() => {
const one = reducer({}, fakeAddQueryAction('any', queryId))
@ -82,8 +82,6 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
three,
toggleField(queryId, {
name: 'a great field',
alias: null,
args: [],
type: 'field',
})
)
@ -186,7 +184,7 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
})
})
describe.only('DE_APPLY_FUNCS_TO_FIELD', () => {
describe('DE_APPLY_FUNCS_TO_FIELD', () => {
it('applies new functions to a field', () => {
const f1 = {name: 'f1', type: 'field'}
const f2 = {name: 'f2', type: 'field'}
@ -223,16 +221,17 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
])
})
// TODO: start here 10/10/2017
it('removes all functions and group by time when one field has no funcs applied', () => {
const f1 = {name: 'f1', type: 'field'}
const f2 = {name: 'f2', type: 'field'}
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn3', 'fn4']},
{name: 'fn1', type: 'func', args: [f1], alias: `fn1_${f1.name}`},
{name: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.name}`},
],
groupBy: {
time: '1m',
@ -242,16 +241,15 @@ describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
}
const action = applyFuncsToField(queryId, {
field: 'f1',
field: {name: 'f1', type: 'field'},
funcs: [],
})
const nextState = reducer(initialState, action)
const actual = nextState[queryId].fields
const expected = [f1, f2]
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: []},
{field: 'f2', funcs: []},
])
expect(actual).to.eql(expected)
expect(nextState[queryId].groupBy.time).to.equal(null)
})
})

View File

@ -77,7 +77,7 @@ describe('Chronograf.Reducers.Kapacitor.queryConfigs', () => {
const three = reducer(two, chooseMeasurement(queryId, 'disk'))
state = reducer(
three,
toggleField(queryId, {field: 'a great field', funcs: []})
toggleField(queryId, {name: 'a great field', funcs: []})
)
})
@ -124,11 +124,11 @@ describe('Chronograf.Reducers.Kapacitor.queryConfigs', () => {
const newState = reducer(
state,
toggleField(queryId, {field: 'a different field', funcs: []})
toggleField(queryId, {name: 'a different field', type: 'field'})
)
expect(newState[queryId].fields.length).to.equal(1)
expect(newState[queryId].fields[0].field).to.equal('a different field')
expect(newState[queryId].fields[0].name).to.equal('a different field')
})
})
@ -138,11 +138,11 @@ describe('Chronograf.Reducers.Kapacitor.queryConfigs', () => {
const newState = reducer(
state,
toggleField(queryId, {field: 'a different field', funcs: []})
toggleField(queryId, {name: 'a different field', type: 'field'})
)
expect(newState[queryId].fields.length).to.equal(1)
expect(newState[queryId].fields[0].field).to.equal('a different field')
expect(newState[queryId].fields[0].name).to.equal('a different field')
})
it('applies no funcs to newly selected fields', () => {
@ -150,49 +150,51 @@ describe('Chronograf.Reducers.Kapacitor.queryConfigs', () => {
const newState = reducer(
state,
toggleField(queryId, {field: 'a different field'})
toggleField(queryId, {name: 'a different field', type: 'field'})
)
expect(newState[queryId].fields[0].funcs).to.equal(undefined)
expect(newState[queryId].fields[0].type).to.equal('field')
})
})
})
describe('KAPA_APPLY_FUNCS_TO_FIELD', () => {
it('applies functions to a field without any existing functions', () => {
const f1 = {name: 'f1', type: 'field'}
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn1']},
],
fields: [f1],
},
}
const action = applyFuncsToField(queryId, {
field: 'f1',
funcs: ['fn3', 'fn4'],
field: {name: 'f1', type: 'field'},
funcs: [{name: 'fn3', type: 'func'}, {name: 'fn4', type: 'func'}],
})
const nextState = reducer(initialState, action)
const actual = nextState[queryId].fields
const expected = [
{name: 'fn3', type: 'func', args: [f1], alias: `fn3_${f1.name}`},
{name: 'fn4', type: 'func', args: [f1], alias: `fn4_${f1.name}`},
]
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: ['fn3', 'fn4']},
{field: 'f2', funcs: ['fn1']},
])
expect(actual).to.eql(expected)
})
it('removes all functions and group by time when one field has no funcs applied', () => {
const f1 = {name: 'f1', type: 'field'}
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn3', 'fn4']},
{name: 'fn3', type: 'func', args: [f1], alias: `fn3_${f1.name}`},
{name: 'fn4', type: 'func', args: [f1], alias: `fn4_${f1.name}`},
],
groupBy: {
time: '1m',
@ -202,16 +204,15 @@ describe('Chronograf.Reducers.Kapacitor.queryConfigs', () => {
}
const action = applyFuncsToField(queryId, {
field: 'f1',
field: f1,
funcs: [],
})
const nextState = reducer(initialState, action)
const actual = nextState[queryId].fields
const expected = [f1]
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: []},
{field: 'f2', funcs: []},
])
expect(actual).to.eql(expected)
expect(nextState[queryId].groupBy.time).to.equal(null)
})
})

View File

@ -2,6 +2,7 @@ import defaultQueryConfig from 'utils/defaultQueryConfig'
import {DEFAULT_DASHBOARD_GROUP_BY_INTERVAL} from 'shared/constants'
import {DEFAULT_DATA_EXPLORER_GROUP_BY_INTERVAL} from 'src/data_explorer/constants'
import {NULL_STRING} from 'shared/constants/queryFillOptions'
import _ from 'lodash'
export function editRawText(query, rawText) {
return Object.assign({}, query, {rawText})
@ -26,6 +27,13 @@ export const chooseMeasurement = (
export const toggleField = (query, {name, type}, isKapacitorRule = false) => {
const {fields, groupBy} = query
if (isKapacitorRule) {
return {
...query,
fields: [{name, type: 'field'}],
}
}
if (!fields || !fields.length) {
return {
...query,
@ -65,6 +73,7 @@ export const toggleField = (query, {name, type}, isKapacitorRule = false) => {
args: [{name, type}],
}
})
// const isSelected = fields.find(f => f.field === field)
// if (isSelected) {
// const nextFields = fields.filter(f => f.field !== field)
@ -82,18 +91,6 @@ export const toggleField = (query, {name, type}, isKapacitorRule = false) => {
// }
// }
// 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: [...fields, ...newField],
@ -129,14 +126,17 @@ export function toggleTagAcceptance(query) {
export function applyFuncsToField(
query,
{field, funcs},
{field, funcs = []},
{preventAutoGroupBy = false, isKapacitorRule = false} = {}
) {
const shouldRemoveFuncs = funcs && funcs.length === 0
const shouldRemoveFuncs = funcs.length === 0
const nextFields = query.fields.reduce((acc, f) => {
// If one field has no funcs, all fields must have no funcs
if (shouldRemoveFuncs) {
return [...acc, f.args.filter(a => a.type === 'field')]
return _.uniq(
[...acc, ...f.args.filter(a => a.type === 'field')],
fld => fld.name
)
}
// If there is a func applied to only one field, add it to the other fields
@ -148,7 +148,7 @@ export function applyFuncsToField(
name: func.name,
type: func.type,
args: [{name: f.name, type: 'field'}],
alias: `${name}_${f.name}`,
alias: `${func.name}_${f.name}`,
}
}),
]
@ -174,7 +174,6 @@ export function applyFuncsToField(
]
}, [])
// console.log('newFuncs: ', newFuncs)
return [...acc, ...newFuncs]
}
@ -184,16 +183,12 @@ export function applyFuncsToField(
const defaultGroupBy = preventAutoGroupBy
? DEFAULT_DATA_EXPLORER_GROUP_BY_INTERVAL
: DEFAULT_DASHBOARD_GROUP_BY_INTERVAL
// If there are no functions, then there should be no GROUP BY time
const nextGroupBy = Object.assign({}, query.groupBy, {
time: shouldRemoveFuncs ? null : defaultGroupBy,
})
const nextTime = shouldRemoveFuncs ? null : defaultGroupBy
const nextGroupBy = {...query.groupBy, time: nextTime}
const nextQuery = {...query, fields: nextFields, groupBy: nextGroupBy}
// fill is not valid for kapacitor query configs since there is no actual
// query and all alert rules create stream-based tasks currently
return isKapacitorRule ? nextQuery : {...nextQuery, fill: NULL_STRING}
return {...query, fields: _.flatten(nextFields), groupBy: nextGroupBy}
}
export function updateRawQuery(query, rawText) {