Merge pull request #1904 from influxdata/feature/tv-url-params

Template Variable URL Param Value Selection
pull/10616/head
Hunter Trujillo 2017-08-22 18:41:31 -06:00 committed by GitHub
commit cda683746a
6 changed files with 100 additions and 6 deletions

View File

@ -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

View File

@ -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]

View File

@ -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))
}

View File

@ -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,

View File

@ -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

View File

@ -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'