Synchronize temp vars with URL query params
Refactor action creator & reducer for updating tempvar overrides. Authored-by: Jared Scheib <jared.scheib@gmail.com>pull/3556/head
parent
187752d49d
commit
fb63b6f63f
|
@ -1,3 +1,6 @@
|
|||
import {push} from 'react-router-redux'
|
||||
import queryString from 'query-string'
|
||||
|
||||
import {
|
||||
getDashboards as getDashboardsAJAX,
|
||||
updateDashboard as updateDashboardAJAX,
|
||||
|
@ -174,14 +177,14 @@ export const templateVariablesSelectedByName = (dashboardID, query) => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const editTemplateVariableOverrides = (
|
||||
export const updateTemplateVariableOverride = (
|
||||
dashboardID,
|
||||
tempVarOverrides
|
||||
updatedTempVarOverride
|
||||
) => ({
|
||||
type: 'EDIT_TEMPLATE_VARIABLE_OVERRIDES',
|
||||
type: 'UPDATE_TEMPLATE_VARIABLE_OVERRIDE',
|
||||
payload: {
|
||||
dashboardID,
|
||||
tempVarOverrides,
|
||||
updatedTempVarOverride,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -362,10 +365,26 @@ export const updateTempVarValues = (source, dashboard) => async dispatch => {
|
|||
const {type, query, id} = tempsWithQueries[i]
|
||||
const parsed = parsers[type](data, query.tagKey || query.measurement)
|
||||
const vals = parsed[type]
|
||||
dispatch(editTemplateVariableValues(dashboard.id, id, vals))
|
||||
dispatch(editTemplateVariableValues(+dashboard.id, id, vals))
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
dispatch(errorThrown(error))
|
||||
}
|
||||
}
|
||||
|
||||
export const updateURLQueryValue = (
|
||||
location,
|
||||
updatedQueryParam
|
||||
) => dispatch => {
|
||||
const updatedLocationQuery = {...location.query, ...updatedQueryParam}
|
||||
const updatedSearchString = queryString.stringify(updatedLocationQuery)
|
||||
const updatedSearch = {search: updatedSearchString}
|
||||
const updatedLocation = {
|
||||
...location,
|
||||
query: updatedLocationQuery,
|
||||
...updatedSearch,
|
||||
}
|
||||
|
||||
dispatch(push(updatedLocation))
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ import {
|
|||
} from 'src/dashboards/actions/cellEditorOverlay'
|
||||
import {showOverlay} from 'src/shared/actions/overlayTechnology'
|
||||
|
||||
import {
|
||||
applyDashboardTempVarOverrides,
|
||||
stripTempVar,
|
||||
} from 'src/dashboards/utils/templateVariableQueryGenerator'
|
||||
|
||||
import {dismissEditingAnnotation} from 'src/shared/actions/annotations'
|
||||
|
||||
import {
|
||||
|
@ -255,15 +260,31 @@ class DashboardPage extends Component {
|
|||
dashboardActions.deleteDashboardCellAsync(dashboard, cell)
|
||||
}
|
||||
|
||||
handleSelectTemplate = templateID => values => {
|
||||
handleSelectTemplate = templateID => value => {
|
||||
const {
|
||||
dashboardActions,
|
||||
dashboard,
|
||||
params: {dashboardID},
|
||||
location,
|
||||
} = this.props
|
||||
dashboardActions.templateVariableSelected(dashboard.id, templateID, [
|
||||
values,
|
||||
])
|
||||
// TODO: block viewer from doing this
|
||||
const currentTempVar = dashboard.templates.find(
|
||||
tempVar => tempVar.id === templateID
|
||||
)
|
||||
const strippedTempVar = stripTempVar(currentTempVar.tempVar)
|
||||
const isTempVarInURLQuery = !!location.query[strippedTempVar]
|
||||
|
||||
if (isTempVarInURLQuery) {
|
||||
const updatedQueryParam = {
|
||||
[strippedTempVar]: value.value,
|
||||
}
|
||||
dashboardActions.updateURLQueryValue(location, updatedQueryParam)
|
||||
dashboardActions.updateTemplateVariableOverride(
|
||||
dashboardID,
|
||||
updatedQueryParam
|
||||
)
|
||||
}
|
||||
dashboardActions.templateVariableSelected(dashboard.id, templateID, [value])
|
||||
dashboardActions.putDashboardByID(dashboardID)
|
||||
}
|
||||
|
||||
|
@ -545,6 +566,7 @@ DashboardPage.propTypes = {
|
|||
gaugeColors: colorsNumberSchema.isRequired,
|
||||
lineColors: colorsStringSchema.isRequired,
|
||||
handleShowOverlay: func.isRequired,
|
||||
tempVarOverrides: shape({}),
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, {params: {dashboardID}}) => {
|
||||
|
@ -553,7 +575,7 @@ const mapStateToProps = (state, {params: {dashboardID}}) => {
|
|||
ephemeral: {inPresentationMode},
|
||||
persisted: {autoRefresh, showTemplateControlBar},
|
||||
},
|
||||
dashboardUI: {dashboards, cellQueryStatus},
|
||||
dashboardUI: {dashboards, cellQueryStatus, tempVarOverrides},
|
||||
sources,
|
||||
dashTimeV1,
|
||||
auth: {me, isUsingAuth},
|
||||
|
@ -573,10 +595,17 @@ const mapStateToProps = (state, {params: {dashboardID}}) => {
|
|||
r => r.dashboardID === idNormalizer(TYPE_ID, dashboardID)
|
||||
) || defaultTimeRange
|
||||
|
||||
const dashboard = dashboards.find(
|
||||
let dashboard = dashboards.find(
|
||||
d => d.id === idNormalizer(TYPE_ID, dashboardID)
|
||||
)
|
||||
|
||||
if (dashboard) {
|
||||
dashboard = applyDashboardTempVarOverrides(
|
||||
dashboard,
|
||||
tempVarOverrides[dashboard.id]
|
||||
)
|
||||
}
|
||||
|
||||
const selectedCell = cell
|
||||
|
||||
return {
|
||||
|
|
|
@ -2,6 +2,8 @@ import _ from 'lodash'
|
|||
import {timeRanges} from 'shared/data/timeRanges'
|
||||
import {NULL_HOVER_TIME} from 'src/shared/constants/tableGraph'
|
||||
|
||||
import {applyDashboardTempVarOverrides} from 'src/dashboards/utils/templateVariableQueryGenerator'
|
||||
|
||||
const {lower, upper} = timeRanges.find(tr => tr.lower === 'now() - 1h')
|
||||
|
||||
const initialState = {
|
||||
|
@ -235,54 +237,28 @@ export default function ui(state = initialState, action) {
|
|||
case 'TEMPLATE_VARIABLES_SELECTED_BY_NAME': {
|
||||
const {dashboardID, query} = action.payload
|
||||
|
||||
const selecteds = Object.keys(query).map(k => ({
|
||||
tempVar: `:${k}:`,
|
||||
selectedValue: query[k],
|
||||
}))
|
||||
|
||||
const makeNewValue = (value, selected) => ({...value, selected})
|
||||
|
||||
const makeNewValues = template => ({
|
||||
...template,
|
||||
values: template.values.map(
|
||||
value =>
|
||||
selecteds.find(({selectedValue}) => selectedValue === value.value)
|
||||
? makeNewValue(value, true)
|
||||
: makeNewValue(value, false)
|
||||
),
|
||||
})
|
||||
|
||||
const makeNewTemplates = templates =>
|
||||
templates.map(
|
||||
template =>
|
||||
selecteds.find(({tempVar}) => tempVar === template.tempVar)
|
||||
? makeNewValues(template)
|
||||
: template
|
||||
)
|
||||
|
||||
const makeNewDashboard = dashboard => ({
|
||||
...dashboard,
|
||||
templates: makeNewTemplates(dashboard.templates),
|
||||
})
|
||||
|
||||
const newDashboards = state.dashboards.map(
|
||||
oldDashboard =>
|
||||
oldDashboard.id === dashboardID
|
||||
? makeNewDashboard(oldDashboard)
|
||||
? applyDashboardTempVarOverrides(oldDashboard, query)
|
||||
: oldDashboard
|
||||
)
|
||||
|
||||
return {...state, dashboards: newDashboards}
|
||||
}
|
||||
|
||||
case 'EDIT_TEMPLATE_VARIABLE_OVERRIDES': {
|
||||
const {dashboardID, tempVarOverrides} = action.payload
|
||||
case 'UPDATE_TEMPLATE_VARIABLE_OVERRIDE': {
|
||||
const {dashboardID, updatedTempVarOverride} = action.payload
|
||||
const updatedTempVarOverrides = {
|
||||
...state.tempVarOverrides[dashboardID],
|
||||
...updatedTempVarOverride,
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
tempVarOverrides: {
|
||||
...state.tempVarOverrides,
|
||||
[dashboardID]: tempVarOverrides,
|
||||
[dashboardID]: updatedTempVarOverrides,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,4 +59,53 @@ export const makeQueryForTemplate = ({influxql, db, measurement, tagKey}) =>
|
|||
.replace(':measurement:', `"${measurement}"`)
|
||||
.replace(':tagKey:', `"${tagKey}"`)
|
||||
|
||||
export const stripTempVar = tempVarName =>
|
||||
tempVarName.substr(1, tempVarName.length - 2)
|
||||
|
||||
const reconcileTempVarsWithOverrides = (currentTempVars, tempVarOverrides) => {
|
||||
if (!tempVarOverrides) {
|
||||
return currentTempVars
|
||||
}
|
||||
const reconciledTempVars = currentTempVars.map(tempVar => {
|
||||
const {tempVar: name, values} = tempVar
|
||||
const strippedTempVar = stripTempVar(name)
|
||||
const overrideValue = tempVarOverrides[strippedTempVar]
|
||||
|
||||
if (overrideValue) {
|
||||
const isValidTempVarOverride = !!values.find(
|
||||
({value}) => value === overrideValue
|
||||
)
|
||||
|
||||
if (isValidTempVarOverride) {
|
||||
const overriddenValues = values.map(tempVarValue => {
|
||||
const {value} = tempVarValue
|
||||
if (value === overrideValue) {
|
||||
return {...tempVarValue, selected: true}
|
||||
}
|
||||
return {...tempVarValue, selected: false}
|
||||
})
|
||||
return {...tempVar, values: overriddenValues}
|
||||
}
|
||||
|
||||
// TODO: generate error notification ?
|
||||
return tempVar
|
||||
}
|
||||
|
||||
return tempVar
|
||||
})
|
||||
|
||||
return reconciledTempVars
|
||||
}
|
||||
|
||||
export const applyDashboardTempVarOverrides = (
|
||||
dashboard,
|
||||
tempVarOverrides
|
||||
) => ({
|
||||
...dashboard,
|
||||
templates: reconcileTempVarsWithOverrides(
|
||||
dashboard.templates,
|
||||
tempVarOverrides
|
||||
),
|
||||
})
|
||||
|
||||
export default generateTemplateVariableQuery
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
import _ from 'lodash'
|
||||
// Middleware generally used for actions needing parsed queryStrings
|
||||
import queryString from 'query-string'
|
||||
|
||||
import {enablePresentationMode} from 'src/shared/actions/app'
|
||||
import {
|
||||
templateVariablesSelectedByName,
|
||||
editTemplateVariableOverrides,
|
||||
updateTemplateVariableOverride,
|
||||
} from 'src/dashboards/actions'
|
||||
|
||||
export const queryStringConfig = () => {
|
||||
let prevPath
|
||||
return next => action => {
|
||||
next(action)
|
||||
const qs = queryString.parse(window.location.search)
|
||||
const queries = queryString.parse(window.location.search)
|
||||
|
||||
// Presentation Mode
|
||||
if (qs.present === 'true') {
|
||||
if (queries.present === 'true') {
|
||||
next(enablePresentationMode())
|
||||
}
|
||||
|
||||
|
@ -24,8 +25,11 @@ export const queryStringConfig = () => {
|
|||
const currentPath = window.location.pathname
|
||||
const dashboardID = currentPath.match(dashboardRegex)[2]
|
||||
if (currentPath !== prevPath) {
|
||||
next(templateVariablesSelectedByName(+dashboardID, qs))
|
||||
next(editTemplateVariableOverrides(dashboardID, qs))
|
||||
next(templateVariablesSelectedByName(+dashboardID, queries))
|
||||
_.each(queries, (v, k) => {
|
||||
const query = {[k]: v}
|
||||
next(updateTemplateVariableOverride(+dashboardID, query))
|
||||
})
|
||||
}
|
||||
|
||||
prevPath = currentPath
|
||||
|
|
Loading…
Reference in New Issue