diff --git a/ui/src/shared/data/timeRanges.js b/ui/src/shared/data/timeRanges.ts similarity index 87% rename from ui/src/shared/data/timeRanges.js rename to ui/src/shared/data/timeRanges.ts index dd52fbcd7..f711a56eb 100644 --- a/ui/src/shared/data/timeRanges.js +++ b/ui/src/shared/data/timeRanges.ts @@ -1,4 +1,12 @@ -export const timeRanges = [ +import {TimeRange} from 'src/types/query' +interface TimeRangeOption extends TimeRange { + defaultGroupBy: string + seconds: number + inputValue: string + menuOption: string +} + +export const timeRanges: TimeRangeOption[] = [ { defaultGroupBy: '10s', seconds: 300, diff --git a/ui/src/utils/buildQueriesForLayouts.ts b/ui/src/utils/buildQueriesForLayouts.ts index cb13fc8b9..24f84c584 100644 --- a/ui/src/utils/buildQueriesForLayouts.ts +++ b/ui/src/utils/buildQueriesForLayouts.ts @@ -1,3 +1,5 @@ +import _ from 'lodash' + import {buildQuery} from 'src/utils/influxql' import {TYPE_SHIFTED, TYPE_QUERY_CONFIG} from 'src/dashboards/constants' import { @@ -5,19 +7,21 @@ import { TEMP_VAR_UPPER_DASHBOARD_TIME, } from 'src/shared/constants' import {timeRanges} from 'src/shared/data/timeRanges' -import {Source, LayoutQuery, TimeRange} from 'src/types' + +import {Cell, CellQuery, LayoutQuery, Source, TimeRange} from 'src/types' const buildCannedDashboardQuery = ( - query: LayoutQuery, + query: LayoutQuery | CellQuery, {lower, upper}: TimeRange, host: string ): string => { const {defaultGroupBy} = timeRanges.find(range => range.lower === lower) || { defaultGroupBy: '5m', } - const {wheres, groupbys} = query let text = query.query + const wheres = _.get(query, 'wheres') + const groupbys = _.get(query, 'groupbys') if (upper) { text += ` where time > '${lower}' AND time < '${upper}'` @@ -48,30 +52,62 @@ const buildCannedDashboardQuery = ( return text } +const addTimeBoundsToRawText = (rawText: string): string => { + if (!rawText) { + return + } + + const dashboardTimeRegex = new RegExp( + `time( )?>( )?${TEMP_VAR_DASHBOARD_TIME}`, + 'g' + ) + const dashboardTimeText: string = `time > ${TEMP_VAR_DASHBOARD_TIME}` + const isUsingTimeSelectorBounds: boolean = !_.isEmpty( + rawText.match(dashboardTimeRegex) + ) + + if (isUsingTimeSelectorBounds) { + const upperTimeBoundRegex = new RegExp('time( )?<', 'g') + const hasUpperTimeBound = !_.isEmpty(rawText.match(upperTimeBoundRegex)) + if ( + rawText.indexOf(TEMP_VAR_UPPER_DASHBOARD_TIME) === -1 && + !hasUpperTimeBound + ) { + const upperDashboardTimeText = `time < ${TEMP_VAR_UPPER_DASHBOARD_TIME}` + const fullTimeText = `${dashboardTimeText} AND ${upperDashboardTimeText}` + const boundedQueryText = rawText.replace(dashboardTimeRegex, fullTimeText) + return boundedQueryText + } + } + return rawText +} + export const buildQueriesForLayouts = ( - cell, + cell: Cell, source: Source, timeRange: TimeRange, host: string -) => { +): CellQuery[] => { return cell.queries.map(query => { - let queryText + let queryText: string // Canned dashboards use an different a schema different from queryConfig. if (query.queryConfig) { const { queryConfig: {database, measurement, fields, shifts, rawText, range}, } = query - const tR = range || { + const tR: TimeRange = range || { upper: TEMP_VAR_UPPER_DASHBOARD_TIME, lower: TEMP_VAR_DASHBOARD_TIME, } queryText = - rawText || buildQuery(TYPE_QUERY_CONFIG, tR, query.queryConfig) - const isParsable = database && measurement && fields.length + addTimeBoundsToRawText(rawText) || + buildQuery(TYPE_QUERY_CONFIG, tR, query.queryConfig) + const isParsable: boolean = + !_.isEmpty(database) && !_.isEmpty(measurement) && fields.length > 0 if (shifts && shifts.length && isParsable) { - const shiftedQueries = shifts + const shiftedQueries: string[] = shifts .filter(s => s.unit) .map(s => buildQuery(TYPE_SHIFTED, timeRange, query.queryConfig, s))