diff --git a/CHANGELOG.md b/CHANGELOG.md index c0c279c3b3e..7e075a520c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/ui/src/shared/utils/featureFlag.ts b/ui/src/shared/utils/featureFlag.ts index 09c3ab62772..f1eb8f7849a 100644 --- a/ui/src/shared/utils/featureFlag.ts +++ b/ui/src/shared/utils/featureFlag.ts @@ -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, } diff --git a/ui/src/timeMachine/components/TagSelector.tsx b/ui/src/timeMachine/components/TagSelector.tsx index 5e07cf668cd..1a2b63a5713 100644 --- a/ui/src/timeMachine/components/TagSelector.tsx +++ b/ui/src/timeMachine/components/TagSelector.tsx @@ -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 { private get header() { const {aggregateFunctionType, index} = this.props - return isFlagEnabled('queryBuilderGrouping') ? ( + return ( - ) : ( - ) } diff --git a/ui/src/timeMachine/selectors/index.test.ts b/ui/src/timeMachine/selectors/index.test.ts index af1a66f2af5..38bce535efd 100644 --- a/ui/src/timeMachine/selectors/index.test.ts +++ b/ui/src/timeMachine/selectors/index.test.ts @@ -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, diff --git a/ui/src/timeMachine/selectors/index.ts b/ui/src/timeMachine/selectors/index.ts index 9e88e47b206..cfc4b3d7cf8 100644 --- a/ui/src/timeMachine/selectors/index.ts +++ b/ui/src/timeMachine/selectors/index.ts @@ -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 => { diff --git a/ui/src/timeMachine/utils/queryBuilder.test.ts b/ui/src/timeMachine/utils/queryBuilder.test.ts index 6134e560494..5bb04e7cc06 100644 --- a/ui/src/timeMachine/utils/queryBuilder.test.ts +++ b/ui/src/timeMachine/utils/queryBuilder.test.ts @@ -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'}, } diff --git a/ui/src/timeMachine/utils/queryBuilder.ts b/ui/src/timeMachine/utils/queryBuilder.ts index 9a8e6fd94bf..2e8c51e3e63 100644 --- a/ui/src/timeMachine/utils/queryBuilder.ts +++ b/ui/src/timeMachine/utils/queryBuilder.ts @@ -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',