From ebe75f1c5bd3a1ff27348c01ee65d4a2764fadab Mon Sep 17 00:00:00 2001 From: Chris Goller Date: Tue, 10 Oct 2017 23:25:00 -0500 Subject: [PATCH] Add functions to handle fields in new queryConfig --- .../data_explorer/components/FieldListItem.js | 37 +++++++++++-------- ui/src/shared/components/FieldList.js | 3 +- ui/src/utils/fields.js | 26 +++++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 ui/src/utils/fields.js diff --git a/ui/src/data_explorer/components/FieldListItem.js b/ui/src/data_explorer/components/FieldListItem.js index 9c730a47c..2140d40a1 100644 --- a/ui/src/data_explorer/components/FieldListItem.js +++ b/ui/src/data_explorer/components/FieldListItem.js @@ -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 (
: null} diff --git a/ui/src/shared/components/FieldList.js b/ui/src/shared/components/FieldList.js index 918cdf994..f0e151403 100644 --- a/ui/src/shared/components/FieldList.js +++ b/ui/src/shared/components/FieldList.js @@ -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 ( diff --git a/ui/src/utils/fields.js b/ui/src/utils/fields.js new file mode 100644 index 000000000..95dd53f2d --- /dev/null +++ b/ui/src/utils/fields.js @@ -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)))