diff --git a/ui/src/dashboards/actions/thunks.ts b/ui/src/dashboards/actions/thunks.ts index a18d64f1999..9aa061233eb 100644 --- a/ui/src/dashboards/actions/thunks.ts +++ b/ui/src/dashboards/actions/thunks.ts @@ -286,7 +286,8 @@ export const getDashboard = (dashboardID: string) => async ( throw new Error(resp.data.message) } - dispatch(hydrateVariables()) + const skipCache = true + dispatch(hydrateVariables(skipCache)) const normDash = normalize( resp.data, diff --git a/ui/src/external/monaco.flux.server.ts b/ui/src/external/monaco.flux.server.ts index 74cdc307676..fb10bba0961 100644 --- a/ui/src/external/monaco.flux.server.ts +++ b/ui/src/external/monaco.flux.server.ts @@ -202,7 +202,7 @@ export class LSPServer { // drift between the parser and the internal representation const variables = getAllVariables(state, contextID) .map(v => asAssignment(v)) - .filter(v => !(v.init.type === 'StringLiteral' && !v.init.value)) + .filter(v => !!v) const file = buildVarsOption(variables) diff --git a/ui/src/timeMachine/actions/queries.ts b/ui/src/timeMachine/actions/queries.ts index 8badd09b173..a350715fcfd 100644 --- a/ui/src/timeMachine/actions/queries.ts +++ b/ui/src/timeMachine/actions/queries.ts @@ -12,6 +12,7 @@ import {runStatusesQuery} from 'src/alerting/utils/statusEvents' // Actions import {notify} from 'src/shared/actions/notifications' +import {hydrateVariables} from 'src/variables/actions/thunks' // Constants import {rateLimitReached, resultTooLarge} from 'src/shared/copy/notifications' @@ -115,6 +116,8 @@ export const executeQueries = () => async (dispatch, getState: GetState) => { try { dispatch(setQueryResults(RemoteDataState.Loading, [], null)) + await dispatch(hydrateVariables()) + //TODO: replace with activeContext selector const contextID = activeTimeMachine.contextID || state.timeMachines.activeTimeMachineID diff --git a/ui/src/types/variables.ts b/ui/src/types/variables.ts index 8722d10ba6c..275fdf962f9 100644 --- a/ui/src/types/variables.ts +++ b/ui/src/types/variables.ts @@ -1,8 +1,13 @@ import {Variable as GenVariable, Label} from 'src/client' -import {VariableProperties as GenVariableProperties} from 'src/client' +import { + QueryVariableProperties as GenQueryVariableProperties, + ConstantVariableProperties as GenConstantVariableProperties, + MapVariableProperties as GenMapVariableProperties, +} from 'src/client' import { VariableArgumentType, + VariableMapObject, QueryArguments, MapArguments, CSVArguments, @@ -16,9 +21,19 @@ export interface SystemVariableProperties { type?: 'system' values?: any } +export interface QueryVariableProperties + extends Omit { + values?: { + query?: string + language?: string + results?: string[] | VariableMapObject + } +} export type VariableProperties = | SystemVariableProperties - | GenVariableProperties + | QueryVariableProperties + | GenConstantVariableProperties + | GenMapVariableProperties export interface Variable extends Omit, 'arguments'> { diff --git a/ui/src/variables/actions/thunks.ts b/ui/src/variables/actions/thunks.ts index 8833d829f6e..16762821669 100644 --- a/ui/src/variables/actions/thunks.ts +++ b/ui/src/variables/actions/thunks.ts @@ -97,7 +97,7 @@ export const getVariables = () => async ( } } -export const hydrateVariables = () => async ( +export const hydrateVariables = (skipCache?: boolean) => async ( dispatch: Dispatch, getState: GetState ) => { @@ -107,7 +107,7 @@ export const hydrateVariables = () => async ( const vals = await hydrateVars(vars, getAllVariablesFromState(state), { orgID: org.id, url: state.links.query.self, - skipCache: true, + skipCache, }).promise vars diff --git a/ui/src/variables/selectors/index.tsx b/ui/src/variables/selectors/index.tsx index 7cee083e7fe..bd55cfb0735 100644 --- a/ui/src/variables/selectors/index.tsx +++ b/ui/src/variables/selectors/index.tsx @@ -175,6 +175,11 @@ export const getVariable = ( if (!vari.selected) { if (vari.arguments.type === 'map') { vari.selected = [Object.keys(vari.arguments.values)[0]] + } else if ( + vari.arguments.type === 'query' && + vari.arguments.values.results + ) { + vari.selected = [vari.arguments.values.results[0]] } else { vari.selected = [vari.arguments.values[0]] } @@ -252,6 +257,9 @@ export const asAssignment = (variable: Variable): VariableAssignment => { } if (variable.arguments.type === 'query') { + if (!variable.selected || !variable.selected[0]) { + return null + } out.init = { type: 'StringLiteral', value: variable.selected[0], diff --git a/ui/src/variables/utils/buildVarsOption.ts b/ui/src/variables/utils/buildVarsOption.ts index 203deb191a6..077a6ef097b 100644 --- a/ui/src/variables/utils/buildVarsOption.ts +++ b/ui/src/variables/utils/buildVarsOption.ts @@ -20,7 +20,7 @@ export const buildVarsOption = (variables: VariableAssignment[]): File => ({ }, init: { type: 'ObjectExpression', - properties: variables.map(assignmentToProperty), + properties: variables.filter(v => !!v).map(assignmentToProperty), }, }, }, diff --git a/ui/src/variables/utils/hydrateVars.ts b/ui/src/variables/utils/hydrateVars.ts index 4fdaeec9a41..2a9894c2045 100644 --- a/ui/src/variables/utils/hydrateVars.ts +++ b/ui/src/variables/utils/hydrateVars.ts @@ -372,7 +372,14 @@ export const hydrateVars = ( node.status === RemoteDataState.Loading try { + // TODO: remove the concept of node.values, just use node.variable node.values = await hydrateVarsHelper(node, options) + if (node.variable.arguments.type === 'query') { + node.variable.arguments.values.results = node.values.values + } else { + node.variable.arguments.values = node.values.values + } + node.variable.selected = node.values.selected node.status = RemoteDataState.Done return Promise.all(node.parents.filter(readyToResolve).map(resolve))