Merge pull request #1904 from influxdata/feature/tv-url-params
Template Variable URL Param Value Selectionpull/10616/head
commit
cda683746a
|
@ -13,6 +13,7 @@
|
|||
### Features
|
||||
1. [#1863](https://github.com/influxdata/chronograf/pull/1863): Improve 'new-sources' server flag example by adding 'type' key
|
||||
1. [#1898](https://github.com/influxdata/chronograf/pull/1898): Add an input and validation to custom time range calendar dropdowns
|
||||
1. [#1904](https://github.com/influxdata/chronograf/pull/1904): Add support for selecting template variables with URL params
|
||||
|
||||
### UI Improvements
|
||||
1. [#1862](https://github.com/influxdata/chronograf/pull/1862): Show "Add Graph" button on cells with no queries
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
renameDashboardCell,
|
||||
syncDashboardCell,
|
||||
templateVariableSelected,
|
||||
templateVariablesSelectedByName,
|
||||
cancelEditCell,
|
||||
} from 'src/dashboards/actions'
|
||||
|
||||
|
@ -20,7 +21,7 @@ const templates = [
|
|||
id: '1',
|
||||
type: 'query',
|
||||
label: 'test query',
|
||||
tempVar: '$REGION',
|
||||
tempVar: ':region:',
|
||||
query: {
|
||||
db: 'db1',
|
||||
rp: 'rp1',
|
||||
|
@ -37,7 +38,7 @@ const templates = [
|
|||
id: '2',
|
||||
type: 'csv',
|
||||
label: 'test csv',
|
||||
tempVar: '$TEMPERATURE',
|
||||
tempVar: ':temperature:',
|
||||
values: [
|
||||
{value: '98.7', type: 'measurement', selected: false},
|
||||
{value: '99.1', type: 'measurement', selected: false},
|
||||
|
@ -167,9 +168,10 @@ describe('DataExplorer.Reducers.UI', () => {
|
|||
state = {
|
||||
dashboards: [dash],
|
||||
}
|
||||
|
||||
const value = dash.templates[0].values[2].value
|
||||
const actual = reducer(
|
||||
{dashboards},
|
||||
state,
|
||||
templateVariableSelected(dash.id, dash.templates[0].id, [{value}])
|
||||
)
|
||||
|
||||
|
@ -178,6 +180,26 @@ describe('DataExplorer.Reducers.UI', () => {
|
|||
expect(actual.dashboards[0].templates[0].values[2].selected).to.equal(true)
|
||||
})
|
||||
|
||||
it('can select template variable values by name', () => {
|
||||
const dash = _.cloneDeep(d1)
|
||||
state = {
|
||||
dashboards: [dash],
|
||||
}
|
||||
|
||||
const selected = {region: 'us-west', temperature: '99.1'}
|
||||
const actual = reducer(
|
||||
state,
|
||||
templateVariablesSelectedByName(dash.id, selected)
|
||||
)
|
||||
|
||||
expect(actual.dashboards[0].templates[0].values[0].selected).to.equal(true)
|
||||
expect(actual.dashboards[0].templates[0].values[1].selected).to.equal(false)
|
||||
expect(actual.dashboards[0].templates[0].values[2].selected).to.equal(false)
|
||||
expect(actual.dashboards[0].templates[1].values[0].selected).to.equal(false)
|
||||
expect(actual.dashboards[0].templates[1].values[1].selected).to.equal(true)
|
||||
expect(actual.dashboards[0].templates[1].values[2].selected).to.equal(false)
|
||||
})
|
||||
|
||||
it('can cancel cell editing', () => {
|
||||
const dash = _.cloneDeep(d1)
|
||||
dash.cells = [editingCell]
|
||||
|
|
|
@ -13,7 +13,10 @@ import {errorThrown} from 'shared/actions/errors'
|
|||
|
||||
import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants'
|
||||
|
||||
import {TEMPLATE_VARIABLE_SELECTED} from 'shared/constants/actionTypes'
|
||||
import {
|
||||
TEMPLATE_VARIABLE_SELECTED,
|
||||
TEMPLATE_VARIABLES_SELECTED_BY_NAME,
|
||||
} from 'shared/constants/actionTypes'
|
||||
import {makeQueryForTemplate} from 'src/dashboards/utils/templateVariableQueryGenerator'
|
||||
import parsers from 'shared/parsing'
|
||||
|
||||
|
@ -134,6 +137,14 @@ export const templateVariableSelected = (dashboardID, templateID, values) => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const templateVariablesSelectedByName = (dashboardID, query) => ({
|
||||
type: TEMPLATE_VARIABLES_SELECTED_BY_NAME,
|
||||
payload: {
|
||||
dashboardID,
|
||||
query,
|
||||
},
|
||||
})
|
||||
|
||||
export const editTemplateVariableValues = (
|
||||
dashboardID,
|
||||
templateID,
|
||||
|
@ -234,7 +245,10 @@ export const deleteDashboardCellAsync = (dashboard, cell) => async dispatch => {
|
|||
|
||||
export const updateTempVarValues = (source, dashboard) => async dispatch => {
|
||||
try {
|
||||
const tempsWithQueries = dashboard.templates.filter(t => !!t.query.influxql)
|
||||
const tempsWithQueries = dashboard.templates.filter(
|
||||
({query}) => !!query.influxql
|
||||
)
|
||||
|
||||
const asyncQueries = tempsWithQueries.map(({query}) =>
|
||||
runTemplateVariableQuery(source, {query: makeQueryForTemplate(query)})
|
||||
)
|
||||
|
@ -251,3 +265,7 @@ export const updateTempVarValues = (source, dashboard) => async dispatch => {
|
|||
dispatch(errorThrown(error))
|
||||
}
|
||||
}
|
||||
|
||||
export const selectTempVarsFromUrl = (dashboardID, query = {}) => dispatch => {
|
||||
dispatch(templateVariablesSelectedByName(dashboardID, query))
|
||||
}
|
||||
|
|
|
@ -40,9 +40,11 @@ class DashboardPage extends Component {
|
|||
dashboardActions: {
|
||||
getDashboardsAsync,
|
||||
updateTempVarValues,
|
||||
selectTempVarsFromUrl,
|
||||
putDashboardByID,
|
||||
},
|
||||
source,
|
||||
location: {query},
|
||||
} = this.props
|
||||
|
||||
const dashboards = await getDashboardsAsync()
|
||||
|
@ -50,6 +52,7 @@ class DashboardPage extends Component {
|
|||
|
||||
// Refresh and persists influxql generated template variable values
|
||||
await updateTempVarValues(source, dashboard)
|
||||
selectTempVarsFromUrl(+dashboardID, query)
|
||||
await putDashboardByID(dashboardID)
|
||||
}
|
||||
|
||||
|
@ -369,6 +372,7 @@ DashboardPage.propTypes = {
|
|||
}).isRequired,
|
||||
location: shape({
|
||||
pathname: string.isRequired,
|
||||
query: shape({}),
|
||||
}).isRequired,
|
||||
dashboardActions: shape({
|
||||
putDashboard: func.isRequired,
|
||||
|
|
|
@ -10,7 +10,10 @@ const initialState = {
|
|||
cellQueryStatus: {queryID: null, status: null},
|
||||
}
|
||||
|
||||
import {TEMPLATE_VARIABLE_SELECTED} from 'shared/constants/actionTypes'
|
||||
import {
|
||||
TEMPLATE_VARIABLE_SELECTED,
|
||||
TEMPLATE_VARIABLES_SELECTED_BY_NAME,
|
||||
} from 'shared/constants/actionTypes'
|
||||
import {TEMPLATE_VARIABLE_TYPES} from 'src/dashboards/constants'
|
||||
|
||||
export default function ui(state = initialState, action) {
|
||||
|
@ -230,6 +233,49 @@ export default function ui(state = initialState, action) {
|
|||
return {...state, dashboards: newDashboards}
|
||||
}
|
||||
|
||||
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)
|
||||
: oldDashboard
|
||||
)
|
||||
|
||||
return {...state, dashboards: newDashboards}
|
||||
}
|
||||
|
||||
case 'EDIT_TEMPLATE_VARIABLE_VALUES': {
|
||||
const {dashboardID, templateID, values} = action.payload
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
export const TEMPLATE_VARIABLE_SELECTED = 'TEMPLATE_VARIABLE_SELECTED'
|
||||
|
||||
export const TEMPLATE_VARIABLES_SELECTED_BY_NAME =
|
||||
'TEMPLATE_VARIABLES_SELECTED_BY_NAME'
|
||||
|
||||
export const LINKS_RECEIVED = 'LINKS_RECEIVED'
|
||||
|
|
Loading…
Reference in New Issue