chore: turn on queryBuilderGrouping flag
parent
b742fee5b2
commit
dd0ab8fe36
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
### Features
|
||||
|
||||
1. [16711](https://github.com/influxdata/influxdb/pull/16711): Query Builder supports group() function (change the dropdown from filter to group)
|
||||
1. [16523](https://github.com/influxdata/influxdb/pull/16523): Change influx packages to be CRD compliant
|
||||
1. [16547](https://github.com/influxdata/influxdb/pull/16547): Allow trailing newline in credentials file and CLI integration
|
||||
1. [16545](https://github.com/influxdata/influxdb/pull/16545): Add support for prefixed cursor search to ForwardCursor types
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ export const OSS_FLAGS = {
|
|||
deleteWithPredicate: false,
|
||||
downloadCellCSV: false,
|
||||
telegrafEditor: false,
|
||||
queryBuilderGrouping: false,
|
||||
customCheckQuery: false,
|
||||
matchingNotificationRules: false,
|
||||
}
|
||||
|
|
@ -15,7 +14,6 @@ export const CLOUD_FLAGS = {
|
|||
cloudBilling: CLOUD_BILLING_VISIBLE, // should be visible in dev and acceptance, but not in cloud
|
||||
downloadCellCSV: false,
|
||||
telegrafEditor: false,
|
||||
queryBuilderGrouping: false,
|
||||
customCheckQuery: false,
|
||||
matchingNotificationRules: false,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import {
|
|||
|
||||
// Utils
|
||||
import DefaultDebouncer from 'src/shared/utils/debouncer'
|
||||
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
|
||||
import {toComponentStatus} from 'src/shared/utils/toComponentStatus'
|
||||
import {
|
||||
getActiveQuery,
|
||||
|
|
@ -106,18 +105,13 @@ class TagSelector extends PureComponent<Props> {
|
|||
private get header() {
|
||||
const {aggregateFunctionType, index} = this.props
|
||||
|
||||
return isFlagEnabled('queryBuilderGrouping') ? (
|
||||
return (
|
||||
<BuilderCard.DropdownHeader
|
||||
options={['filter', 'group']}
|
||||
selectedOption={this.renderAggregateFunctionType(aggregateFunctionType)}
|
||||
onDelete={index !== 0 && this.handleRemoveTagSelector}
|
||||
onSelect={this.handleAggregateFunctionSelect}
|
||||
/>
|
||||
) : (
|
||||
<BuilderCard.Header
|
||||
title={this.renderAggregateFunctionType(aggregateFunctionType)}
|
||||
onDelete={index !== 0 && this.handleRemoveTagSelector}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,14 +61,17 @@ describe('the Time Machine reducer', () => {
|
|||
{
|
||||
key: '_measurement',
|
||||
values: ['mem'],
|
||||
aggregateFunctionType: 'filter',
|
||||
},
|
||||
{
|
||||
key: '_field',
|
||||
values: ['active'],
|
||||
aggregateFunctionType: 'filter',
|
||||
},
|
||||
{
|
||||
key: 'host',
|
||||
values: [],
|
||||
aggregateFunctionType: 'filter',
|
||||
},
|
||||
],
|
||||
functions: [
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
// Funcs
|
||||
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
jest.mock('src/shared/utils/featureFlag')
|
||||
|
||||
import {
|
||||
getActiveTagValues,
|
||||
getStartTime,
|
||||
|
|
@ -137,33 +132,13 @@ describe('getting active tag values', () => {
|
|||
values: ['foo_computer'],
|
||||
},
|
||||
]
|
||||
beforeEach(() => {
|
||||
mocked(isFlagEnabled).mockReset()
|
||||
})
|
||||
|
||||
it("returns the active query tag values when the isFlagEnabled('queryBuilderGrouping') is toggled off", () => {
|
||||
mocked(isFlagEnabled).mockImplementation(() => {
|
||||
return false
|
||||
})
|
||||
|
||||
it('returns the active query tag values when the function is filter', () => {
|
||||
const actualTags = getActiveTagValues(activeQueryTags, 'filter', 2)
|
||||
expect(actualTags).toEqual(activeQueryTags[2].values)
|
||||
})
|
||||
|
||||
it("returns the active query tag values when the isFlagEnabled('queryBuilderGrouping') is toggled on, but the function is filter", () => {
|
||||
mocked(isFlagEnabled).mockImplementation(() => {
|
||||
return true
|
||||
})
|
||||
|
||||
const actualTags = getActiveTagValues(activeQueryTags, 'filter', 2)
|
||||
expect(actualTags).toEqual(activeQueryTags[2].values)
|
||||
})
|
||||
|
||||
it("returns all previous tag values when the isFlagEnabled('queryBuilderGrouping') is toggled on and the function is group", () => {
|
||||
mocked(isFlagEnabled).mockImplementation(() => {
|
||||
return true
|
||||
})
|
||||
|
||||
it('returns all previous tag values when the function is group', () => {
|
||||
const actualTags = getActiveTagValues(activeQueryTags, 'group', 2)
|
||||
expect(actualTags).toEqual([
|
||||
...activeQueryTags[0].values,
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ import {
|
|||
durationToMilliseconds,
|
||||
} from 'src/shared/utils/duration'
|
||||
|
||||
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
|
||||
|
||||
// Types
|
||||
import {
|
||||
QueryView,
|
||||
|
|
@ -252,10 +250,7 @@ export const getActiveTagValues = (
|
|||
index: number
|
||||
): string[] => {
|
||||
// if we're grouping, we want to be able to group on all previous tags
|
||||
if (
|
||||
isFlagEnabled('queryBuilderGrouping') &&
|
||||
aggregateFunctionType === 'group'
|
||||
) {
|
||||
if (aggregateFunctionType === 'group') {
|
||||
const values = []
|
||||
activeQueryBuilderTags.forEach(tag => {
|
||||
tag.values.forEach(value => {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ describe('buildQuery', () => {
|
|||
test('single tag', () => {
|
||||
const config: BuilderConfig = {
|
||||
buckets: ['b0'],
|
||||
tags: [{key: '_measurement', values: ['m0']}],
|
||||
tags: [
|
||||
{key: '_measurement', values: ['m0'], aggregateFunctionType: 'filter'},
|
||||
],
|
||||
functions: [],
|
||||
aggregateWindow: {period: 'auto'},
|
||||
}
|
||||
|
|
@ -16,7 +18,6 @@ describe('buildQuery', () => {
|
|||
|> filter(fn: (r) => r._measurement == "m0")`
|
||||
|
||||
const actual = buildQuery(config)
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
})
|
||||
|
||||
|
|
@ -24,8 +25,12 @@ describe('buildQuery', () => {
|
|||
const config: BuilderConfig = {
|
||||
buckets: ['b0'],
|
||||
tags: [
|
||||
{key: '_measurement', values: ['m0', 'm1']},
|
||||
{key: '_field', values: ['f0', 'f1']},
|
||||
{
|
||||
key: '_measurement',
|
||||
values: ['m0', 'm1'],
|
||||
aggregateFunctionType: 'filter',
|
||||
},
|
||||
{key: '_field', values: ['f0', 'f1'], aggregateFunctionType: 'filter'},
|
||||
],
|
||||
functions: [],
|
||||
aggregateWindow: {period: 'auto'},
|
||||
|
|
@ -44,7 +49,9 @@ describe('buildQuery', () => {
|
|||
test('single tag, multiple functions', () => {
|
||||
const config: BuilderConfig = {
|
||||
buckets: ['b0'],
|
||||
tags: [{key: '_measurement', values: ['m0']}],
|
||||
tags: [
|
||||
{key: '_measurement', values: ['m0'], aggregateFunctionType: 'filter'},
|
||||
],
|
||||
functions: [{name: 'mean'}, {name: 'median'}],
|
||||
aggregateWindow: {period: 'auto'},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import {
|
|||
WINDOW_PERIOD,
|
||||
} from 'src/variables/constants'
|
||||
import {AGG_WINDOW_AUTO} from 'src/timeMachine/constants/queryBuilder'
|
||||
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
|
||||
|
||||
export function isConfigValid(builderConfig: BuilderConfig): boolean {
|
||||
const {buckets, tags} = builderConfig
|
||||
|
|
@ -95,35 +94,18 @@ export function buildQuery(builderConfig: BuilderConfig): string {
|
|||
const {functions} = builderConfig
|
||||
|
||||
let query: string
|
||||
const helper = isFlagEnabled('queryBuilderGrouping')
|
||||
? buildQueryHelperButWithGrouping
|
||||
: buildQueryHelper
|
||||
|
||||
if (functions.length) {
|
||||
query = functions.map(f => helper(builderConfig, f)).join('\n\n')
|
||||
query = functions
|
||||
.map(f => buildQueryFromConfig(builderConfig, f))
|
||||
.join('\n\n')
|
||||
} else {
|
||||
query = helper(builderConfig, null)
|
||||
query = buildQueryFromConfig(builderConfig, null)
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
function buildQueryHelper(
|
||||
builderConfig: BuilderConfig,
|
||||
fn?: BuilderConfig['functions'][0]
|
||||
): string {
|
||||
const [bucket] = builderConfig.buckets
|
||||
const tagFilterCall = formatTagFilterCall(builderConfig.tags)
|
||||
const {aggregateWindow} = builderConfig
|
||||
const fnCall = fn ? formatFunctionCall(fn, aggregateWindow.period) : ''
|
||||
|
||||
const query = `from(bucket: "${bucket}")
|
||||
|> range(start: ${OPTION_NAME}.${TIME_RANGE_START}, stop: ${OPTION_NAME}.${TIME_RANGE_STOP})${tagFilterCall}${fnCall}`
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
function buildQueryHelperButWithGrouping(
|
||||
function buildQueryFromConfig(
|
||||
builderConfig: BuilderConfig,
|
||||
fn?: BuilderConfig['functions'][0]
|
||||
): string {
|
||||
|
|
@ -201,23 +183,6 @@ const formatPeriod = (period: string): string => {
|
|||
return period
|
||||
}
|
||||
|
||||
function formatTagFilterCall(tagsSelections: BuilderConfig['tags']) {
|
||||
if (!tagsSelections.length) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const calls = tagsSelections
|
||||
.filter(({key, values}) => key && values.length)
|
||||
.map(({key, values}) => {
|
||||
const fnBody = values.map(value => `r.${key} == "${value}"`).join(' or ')
|
||||
|
||||
return `|> filter(fn: (r) => ${fnBody})`
|
||||
})
|
||||
.join('\n ')
|
||||
|
||||
return `\n ${calls}`
|
||||
}
|
||||
|
||||
export enum ConfirmationState {
|
||||
NotRequired = 'no confirmation required',
|
||||
Required = 'confirmation required',
|
||||
|
|
|
|||
Loading…
Reference in New Issue