Add functions to handle fields in new queryConfig

pull/2128/head
Chris Goller 2017-10-10 23:25:00 -05:00 committed by Andrew Watkins
parent 326a00b153
commit ebe75f1c5b
3 changed files with 49 additions and 17 deletions

View File

@ -1,16 +1,19 @@
import _ from 'lodash'
import React, {PropTypes} from 'react'
import classnames from 'classnames'
import _ from 'lodash'
import FunctionSelector from 'shared/components/FunctionSelector'
import {numFunctions, fieldNamesDeep, functionNames} from 'utils/fields'
const {string, shape, func, arrayOf, bool} = PropTypes
const FieldListItem = React.createClass({
propTypes: {
fieldFunc: shape({
field: string.isRequired,
funcs: arrayOf(string).isRequired,
}).isRequired,
fieldFunc: arrayOf(
shape({
type: string,
name: string,
})
).isRequired,
isSelected: bool.isRequired,
onToggleField: func.isRequired,
onApplyFuncsToField: func.isRequired,
@ -46,17 +49,19 @@ const FieldListItem = React.createClass({
render() {
const {isKapacitorRule, fieldFunc, isSelected} = this.props
const {isOpen} = this.state
const {field: fieldText} = fieldFunc
const fieldText = _.head(fieldNamesDeep(fieldFunc))
const funcs = functionNames(fieldFunc)
let fieldFuncsLabel
if (!fieldFunc.funcs.length) {
fieldFuncsLabel = '0 Functions'
} else if (fieldFunc.funcs.length === 1) {
fieldFuncsLabel = `${fieldFunc.funcs.length} Function`
} else if (fieldFunc.funcs.length > 1) {
fieldFuncsLabel = `${fieldFunc.funcs.length} Functions`
const num = numFunctions(fieldFunc)
switch (num) {
case 0:
fieldFuncsLabel = '0 Functions'
case 1:
fieldFuncsLabel = `${num} Function`
default:
fieldFuncsLabel = `${num} Functions`
}
return (
<div key={fieldFunc}>
<div
@ -74,8 +79,8 @@ const FieldListItem = React.createClass({
? <div
className={classnames('btn btn-xs', {
active: isOpen,
'btn-default': !fieldFunc.funcs.length,
'btn-primary': fieldFunc.funcs.length,
'btn-default': !num,
'btn-primary': num,
})}
onClick={this.toggleFunctionsMenu}
data-test={`query-builder-list-item-function-${fieldText}`}
@ -87,7 +92,7 @@ const FieldListItem = React.createClass({
{isSelected && isOpen
? <FunctionSelector
onApply={this.handleApplyFunctions}
selectedItems={fieldFunc.funcs || []}
selectedItems={funcs}
singleSelect={isKapacitorRule}
/>
: null}

View File

@ -8,6 +8,7 @@ import FancyScrollbar from 'shared/components/FancyScrollbar'
import {showFieldKeys} from 'shared/apis/metaQuery'
import showFieldKeysParser from 'shared/parsing/showFieldKeys'
import {numFunctions} from 'utils/fields'
class FieldList extends Component {
constructor(props) {
@ -85,7 +86,7 @@ class FieldList extends Component {
isInDataExplorer,
} = this.props
const hasAggregates = fields.some(f => f.funcs && f.funcs.length)
const hasAggregates = numFunctions(fields) > 0
const hasGroupByTime = groupBy.time
return (

26
ui/src/utils/fields.js Normal file
View File

@ -0,0 +1,26 @@
import _ from 'lodash'
j
// functions returns all top-level fields with type
export const ofType = (fields, type) =>
_.filter(fields, f => _.get(f, 'type') === type)
// functions returns all top-level functions in fields
export const functions = fields => ofType(fields, 'func')
// numFunctions searches queryConfig fields for functions
export const numFunctions = fields => _.size(functions(fields))
// functionNames returns the names of all top-level functions
export const functionNames = fields => _.map(functions(fields), f => f.name)
// getFields returns all of the top-level fields of type field
export const getFields = fields => ofType(fields, 'field')
export const fieldsDeep = fields =>
_.uniqBy(walk(fields, f => getFields(f)), 'name')
export const fieldNamesDeep = fields =>
_.map(fieldsDeep(fields), f => _.get(f, 'name'))
export const walk = (fields, fn) =>
_.foreach(fields, f => _.concat(fn(f), walk(_.get(f, 'args', []), fn)))