Add timeRangeStart variable to queries as preamble
parent
3660cfc34a
commit
e7c33d5c8e
|
@ -1,3 +1,5 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
import Deferred from 'src/utils/Deferred'
|
||||
|
||||
import {InfluxLanguage} from 'src/types/v2/dashboards'
|
||||
|
@ -19,8 +21,21 @@ interface XHRError extends Error {
|
|||
export const executeQuery = async (
|
||||
url: string,
|
||||
query: string,
|
||||
language: InfluxLanguage = InfluxLanguage.Flux
|
||||
language: InfluxLanguage = InfluxLanguage.Flux,
|
||||
variables?: {[key: string]: string}
|
||||
): Promise<ExecuteFluxQueryResult> => {
|
||||
let preamble = ''
|
||||
|
||||
if (variables && language === InfluxLanguage.Flux) {
|
||||
preamble = _.reduce(
|
||||
variables,
|
||||
(result, value, name) => `${result}${name} = ${value}\n`,
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
query = `${preamble}${query}`
|
||||
|
||||
// We're using `XMLHttpRequest` directly here rather than through `axios` so
|
||||
// that we can poll the response size as it comes back. If the response size
|
||||
// is greater than a predefined limit, we close the HTTP connection and
|
||||
|
@ -133,10 +148,11 @@ export const executeQuery = async (
|
|||
}
|
||||
|
||||
export const executeQueries = async (
|
||||
queries: URLQuery[]
|
||||
queries: URLQuery[],
|
||||
variables?: {[key: string]: string}
|
||||
): Promise<ExecuteFluxQueryResult[]> => {
|
||||
const promise = Promise.all(
|
||||
queries.map(({url, text, type}) => executeQuery(url, text, type))
|
||||
queries.map(({url, text, type}) => executeQuery(url, text, type, variables))
|
||||
)
|
||||
|
||||
return promise
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
const Conditional = ({
|
||||
isRendered,
|
||||
children,
|
||||
}: {
|
||||
isRendered: boolean
|
||||
children: JSX.Element
|
||||
}): JSX.Element => {
|
||||
if (isRendered) {
|
||||
return children
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default Conditional
|
|
@ -9,6 +9,7 @@ import QueryViewSwitcher from 'src/shared/components/QueryViewSwitcher'
|
|||
|
||||
// Utils
|
||||
import {GlobalAutoRefresher} from 'src/utils/AutoRefresher'
|
||||
import {timeRangeVariables} from 'src/shared/utils/queryBuilder'
|
||||
|
||||
// Types
|
||||
import {TimeRange} from 'src/types'
|
||||
|
@ -65,6 +66,7 @@ class RefreshingView extends PureComponent<Props, State> {
|
|||
submitToken={submitToken}
|
||||
queries={this.queries}
|
||||
key={manualRefresh}
|
||||
variables={{...timeRangeVariables(timeRange)}}
|
||||
>
|
||||
{({tables, loading, error, isInitialFetch}) => {
|
||||
return (
|
||||
|
|
|
@ -15,9 +15,10 @@ const INITIAL_RESIZER_HANDLE = 0.6
|
|||
|
||||
// Utils
|
||||
import {getActiveTimeMachine} from 'src/shared/selectors/timeMachines'
|
||||
import {timeRangeVariables} from 'src/shared/utils/queryBuilder'
|
||||
|
||||
// Types
|
||||
import {AppState, DashboardQuery} from 'src/types/v2'
|
||||
import {AppState, DashboardQuery, TimeRange} from 'src/types/v2'
|
||||
|
||||
// Styles
|
||||
import './TimeMachine.scss'
|
||||
|
@ -25,6 +26,7 @@ import './TimeMachine.scss'
|
|||
interface StateProps {
|
||||
queries: DashboardQuery[]
|
||||
submitToken: number
|
||||
timeRange: TimeRange
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -43,7 +45,7 @@ class TimeMachine extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {queries, submitToken} = this.props
|
||||
const {queries, submitToken, timeRange} = this.props
|
||||
const {resizerHandlePosition} = this.state
|
||||
|
||||
return (
|
||||
|
@ -52,6 +54,7 @@ class TimeMachine extends Component<Props, State> {
|
|||
queries={queries}
|
||||
submitToken={submitToken}
|
||||
implicitSubmit={false}
|
||||
variables={{...timeRangeVariables(timeRange)}}
|
||||
>
|
||||
{queriesState => (
|
||||
<DraggableResizer
|
||||
|
@ -82,10 +85,11 @@ class TimeMachine extends Component<Props, State> {
|
|||
|
||||
const mstp = (state: AppState) => {
|
||||
const timeMachine = getActiveTimeMachine(state)
|
||||
const {timeRange} = timeMachine
|
||||
const queries = get(timeMachine, 'view.properties.queries', [])
|
||||
const submitToken = timeMachine.submitToken
|
||||
|
||||
return {queries, submitToken}
|
||||
return {queries, submitToken, timeRange}
|
||||
}
|
||||
|
||||
export default connect<StateProps, {}, {}>(
|
||||
|
|
|
@ -33,6 +33,7 @@ interface StateProps {
|
|||
|
||||
interface OwnProps {
|
||||
queries: DashboardQuery[]
|
||||
variables?: {[key: string]: string}
|
||||
submitToken: number
|
||||
implicitSubmit?: boolean
|
||||
inView?: boolean
|
||||
|
@ -121,7 +122,7 @@ class TimeSeries extends Component<Props, State> {
|
|||
})
|
||||
|
||||
try {
|
||||
const results = await this.executeQueries(queries)
|
||||
const results = await this.executeQueries(queries, this.props.variables)
|
||||
const tables = flatten(results.map(r => parseResponse(r.csv)))
|
||||
const files = results.map(r => r.csv)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import CellHeader from 'src/shared/components/cells/CellHeader'
|
|||
import CellContext from 'src/shared/components/cells/CellContext'
|
||||
import ViewComponent from 'src/shared/components/cells/View'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import Conditional from 'src/shared/components/Conditional'
|
||||
|
||||
// Actions
|
||||
import {readView} from 'src/dashboards/actions/v2/views'
|
||||
|
@ -111,19 +112,17 @@ class CellComponent extends Component<Props> {
|
|||
onEditCell,
|
||||
} = this.props
|
||||
|
||||
if (viewStatus !== RemoteDataState.Done) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<ViewComponent
|
||||
view={view}
|
||||
onZoom={onZoom}
|
||||
timeRange={timeRange}
|
||||
autoRefresh={autoRefresh}
|
||||
manualRefresh={manualRefresh}
|
||||
onEditCell={onEditCell}
|
||||
/>
|
||||
<Conditional isRendered={viewStatus !== RemoteDataState.Done}>
|
||||
<ViewComponent
|
||||
view={view}
|
||||
onZoom={onZoom}
|
||||
timeRange={timeRange}
|
||||
autoRefresh={autoRefresh}
|
||||
manualRefresh={manualRefresh}
|
||||
onEditCell={onEditCell}
|
||||
/>
|
||||
</Conditional>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {BuilderConfig} from 'src/types/v2'
|
||||
import {BuilderConfig, TimeRange} from 'src/types/v2'
|
||||
import {FUNCTIONS} from 'src/shared/constants/queryBuilder'
|
||||
|
||||
const DEFAULT_WINDOW_INTERVAL = '10s'
|
||||
|
@ -15,6 +15,18 @@ const WINDOW_INTERVALS = {
|
|||
'30d': '6h',
|
||||
}
|
||||
|
||||
export const timeRangeVariables = (
|
||||
timeRange: TimeRange
|
||||
): {[key: string]: string} => {
|
||||
const result: {[key: string]: string} = {}
|
||||
|
||||
result.timeRangeStart = timeRange.lower
|
||||
.replace('now()', '')
|
||||
.replace(/\s/g, '')
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function isConfigValid(builderConfig: BuilderConfig): boolean {
|
||||
const {buckets, measurements} = builderConfig
|
||||
const isConfigValid = buckets.length >= 1 && measurements.length >= 1
|
||||
|
|
Loading…
Reference in New Issue