Refactor dashboard URL queries and temp var handling into thunks
Refactor zoomedTimeRange to be on DashboardPage props & use redux. This cleans up DashboardPage considerably by adding a dedicated loadDashboard action creator & reducer, moving zoomedTimeRange out of component state and into redux state, and moving all of the URL queries and template variable reconciliation into a single series of async action creators (thunks) that hydrate a dashboard's template variables and then reconcile them with URL queries. This also moves URL query parsing for tempvars and time ranges back out of the middleware and into this new dashboard thunk series. This also renames a number of fns and vars for clarity.pull/3556/head
parent
2e655f46fb
commit
f7f8b2d93a
|
@ -1,9 +1,11 @@
|
|||
import {bindActionCreators} from 'redux'
|
||||
import {push} from 'react-router-redux'
|
||||
import _ from 'lodash'
|
||||
import queryString from 'query-string'
|
||||
import {push} from 'react-router-redux'
|
||||
|
||||
import {
|
||||
getDashboards as getDashboardsAJAX,
|
||||
getDashboard as getDashboardAJAX,
|
||||
updateDashboard as updateDashboardAJAX,
|
||||
deleteDashboard as deleteDashboardAJAX,
|
||||
updateDashboardCell as updateDashboardCellAJAX,
|
||||
|
@ -15,7 +17,11 @@ import {
|
|||
import {notify} from 'shared/actions/notifications'
|
||||
import {errorThrown} from 'shared/actions/errors'
|
||||
|
||||
import {generateURLQueryFromTempVars} from 'src/dashboards/utils/tempVars'
|
||||
import {
|
||||
generateURLQueryFromTempVars,
|
||||
findInvalidTempVarsInURLQuery,
|
||||
} from 'src/dashboards/utils/tempVars'
|
||||
import {validTimeRange, validAbsoluteTimeRange} from 'src/dashboards/utils/time'
|
||||
import {
|
||||
getNewDashboardCell,
|
||||
getClonedDashboardCell,
|
||||
|
@ -25,11 +31,19 @@ import {
|
|||
notifyDashboardDeleteFailed,
|
||||
notifyCellAdded,
|
||||
notifyCellDeleted,
|
||||
notifyDashboardNotFound,
|
||||
notifyInvalidTempVarValueInURLQuery,
|
||||
notifyInvalidZoomedTimeRangeValueInURLQuery,
|
||||
notifyInvalidTimeRangeValueInURLQuery,
|
||||
} from 'shared/copy/notifications'
|
||||
|
||||
import {makeQueryForTemplate} from 'src/dashboards/utils/tempVars'
|
||||
import parsers from 'shared/parsing'
|
||||
|
||||
import idNormalizer, {TYPE_ID} from 'src/normalizers/id'
|
||||
|
||||
import {defaultTimeRange} from 'src/shared/data/timeRanges'
|
||||
|
||||
export const loadDashboards = (dashboards, dashboardID) => ({
|
||||
type: 'LOAD_DASHBOARDS',
|
||||
payload: {
|
||||
|
@ -38,6 +52,13 @@ export const loadDashboards = (dashboards, dashboardID) => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const loadDashboard = dashboard => ({
|
||||
type: 'LOAD_DASHBOARD',
|
||||
payload: {
|
||||
dashboard,
|
||||
},
|
||||
})
|
||||
|
||||
export const setDashTimeV1 = (dashboardID, timeRange) => ({
|
||||
type: 'SET_DASHBOARD_TIME_V1',
|
||||
payload: {
|
||||
|
@ -58,6 +79,13 @@ export const setTimeRange = timeRange => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const setZoomedTimeRange = zoomedTimeRange => ({
|
||||
type: 'SET_DASHBOARD_ZOOMED_TIME_RANGE',
|
||||
payload: {
|
||||
zoomedTimeRange,
|
||||
},
|
||||
})
|
||||
|
||||
export const updateDashboard = dashboard => ({
|
||||
type: 'UPDATE_DASHBOARD',
|
||||
payload: {
|
||||
|
@ -161,11 +189,11 @@ export const templateVariableSelected = (dashboardID, templateID, values) => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const templateVariablesSelectedByName = (dashboardID, query) => ({
|
||||
export const templateVariablesSelectedByName = (dashboardID, queries) => ({
|
||||
type: 'TEMPLATE_VARIABLES_SELECTED_BY_NAME',
|
||||
payload: {
|
||||
dashboardID,
|
||||
query,
|
||||
queries,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -211,6 +239,18 @@ export const getDashboardsAsync = () => async dispatch => {
|
|||
}
|
||||
}
|
||||
|
||||
export const getDashboardAsync = dashboardID => async dispatch => {
|
||||
try {
|
||||
const {data: dashboard} = await getDashboardAJAX(dashboardID)
|
||||
dispatch(loadDashboard(dashboard))
|
||||
return dashboard
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
dispatch(errorThrown(error))
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const removeUnselectedTemplateValues = dashboard => {
|
||||
const templates = dashboard.templates.map(template => {
|
||||
if (template.type === 'csv') {
|
||||
|
@ -330,8 +370,15 @@ export const deleteDashboardCellAsync = (dashboard, cell) => async dispatch => {
|
|||
}
|
||||
}
|
||||
|
||||
export const hydrateTempVarValues = (source, dashboard) => async dispatch => {
|
||||
export const hydrateTempVarValuesAsync = (dashboardID, source) => async (
|
||||
dispatch,
|
||||
getState
|
||||
) => {
|
||||
try {
|
||||
const dashboard = getState().dashboardUI.dashboards.find(
|
||||
d => d.id === dashboardID
|
||||
)
|
||||
|
||||
const tempsWithQueries = dashboard.templates.filter(
|
||||
({query}) => !!query.influxql
|
||||
)
|
||||
|
@ -402,3 +449,131 @@ export const syncURLQueryFromTempVars = (
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
const syncDashboardTempVarsFromURLQueries = (dashboardID, urlQueries) => (
|
||||
dispatch,
|
||||
getState
|
||||
) => {
|
||||
const dashboard = getState().dashboardUI.dashboards.find(
|
||||
d => d.id === dashboardID
|
||||
)
|
||||
|
||||
const urlQueryTempVarsWithInvalidValues = findInvalidTempVarsInURLQuery(
|
||||
dashboard.templates,
|
||||
urlQueries
|
||||
)
|
||||
urlQueryTempVarsWithInvalidValues.forEach(invalidURLQuery => {
|
||||
dispatch(notify(notifyInvalidTempVarValueInURLQuery(invalidURLQuery)))
|
||||
})
|
||||
|
||||
dispatch(templateVariablesSelectedByName(dashboardID, urlQueries))
|
||||
}
|
||||
|
||||
const syncDashboardTimeRangeFromURLQueries = (
|
||||
dashboardID,
|
||||
urlQueries,
|
||||
location
|
||||
) => (dispatch, getState) => {
|
||||
const dashboard = getState().dashboardUI.dashboards.find(
|
||||
d => d.id === dashboardID
|
||||
)
|
||||
|
||||
const {
|
||||
upper = null,
|
||||
lower = null,
|
||||
zoomedUpper = null,
|
||||
zoomedLower = null,
|
||||
} = urlQueries
|
||||
|
||||
let timeRange
|
||||
const {dashTimeV1} = getState()
|
||||
|
||||
const timeRangeFromQueries = {
|
||||
upper: urlQueries.upper,
|
||||
lower: urlQueries.lower,
|
||||
}
|
||||
const timeRangeOrNull = validTimeRange(timeRangeFromQueries)
|
||||
|
||||
if (timeRangeOrNull) {
|
||||
timeRange = timeRangeOrNull
|
||||
} else {
|
||||
const dashboardTimeRange = dashTimeV1.ranges.find(
|
||||
r => r.dashboardID === idNormalizer(TYPE_ID, dashboardID)
|
||||
)
|
||||
|
||||
timeRange = dashboardTimeRange || defaultTimeRange
|
||||
|
||||
if (timeRangeFromQueries.lower || timeRangeFromQueries.upper) {
|
||||
dispatch(
|
||||
notify(notifyInvalidTimeRangeValueInURLQuery(timeRangeFromQueries))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(setDashTimeV1(dashboardID, timeRange))
|
||||
|
||||
if (!validAbsoluteTimeRange({lower: zoomedLower, upper: zoomedUpper})) {
|
||||
if (zoomedLower || zoomedUpper) {
|
||||
dispatch(notify(notifyInvalidZoomedTimeRangeValueInURLQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(setZoomedTimeRange({zoomedLower, zoomedUpper}))
|
||||
|
||||
const urlQueryTimeRanges = {
|
||||
upper,
|
||||
lower,
|
||||
zoomedUpper,
|
||||
zoomedLower,
|
||||
}
|
||||
dispatch(
|
||||
syncURLQueryFromTempVars(
|
||||
location,
|
||||
dashboard.templates,
|
||||
[],
|
||||
urlQueryTimeRanges
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const syncDashboardFromURLQueries = (dashboardID, location) => dispatch => {
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
|
||||
dispatch(syncDashboardTempVarsFromURLQueries(dashboardID, urlQueries))
|
||||
dispatch(
|
||||
syncDashboardTimeRangeFromURLQueries(dashboardID, urlQueries, location)
|
||||
)
|
||||
}
|
||||
|
||||
export const getDashboardWithHydratedAndSyncedTempVarsAsync = (
|
||||
dashboardID,
|
||||
source,
|
||||
router,
|
||||
location
|
||||
) => async dispatch => {
|
||||
const dashboard = await bindActionCreators(getDashboardAsync, dispatch)(
|
||||
dashboardID,
|
||||
source,
|
||||
router
|
||||
)
|
||||
if (!dashboard) {
|
||||
router.push(`/sources/${source.id}/dashboards`)
|
||||
dispatch(notify(notifyDashboardNotFound(dashboardID)))
|
||||
return
|
||||
}
|
||||
|
||||
await bindActionCreators(hydrateTempVarValuesAsync, dispatch)(
|
||||
+dashboardID,
|
||||
source
|
||||
)
|
||||
|
||||
dispatch(syncDashboardFromURLQueries(+dashboardID, location))
|
||||
}
|
||||
|
||||
export const setZoomedTimeRangeAsync = (
|
||||
zoomedTimeRange,
|
||||
location
|
||||
) => async dispatch => {
|
||||
dispatch(setZoomedTimeRange(zoomedTimeRange))
|
||||
dispatch(syncURLQueryFromQueriesObject(location, zoomedTimeRange))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,18 @@ export function getDashboards() {
|
|||
})
|
||||
}
|
||||
|
||||
export const getDashboard = async dashboardID => {
|
||||
try {
|
||||
return await AJAX({
|
||||
method: 'GET',
|
||||
url: `/chronograf/v1/dashboards/${dashboardID}`,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export function updateDashboard(dashboard) {
|
||||
return AJAX({
|
||||
method: 'PUT',
|
||||
|
|
|
@ -5,7 +5,6 @@ import {withRouter} from 'react-router'
|
|||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import _ from 'lodash'
|
||||
import queryString from 'query-string'
|
||||
|
||||
import {isUserAuthorized, EDITOR_ROLE} from 'src/auth/Authorized'
|
||||
|
||||
|
@ -30,11 +29,7 @@ import {
|
|||
} from 'src/dashboards/actions/cellEditorOverlay'
|
||||
import {showOverlay} from 'src/shared/actions/overlayTechnology'
|
||||
|
||||
import {
|
||||
applyDashboardTempVarOverrides,
|
||||
stripTempVar,
|
||||
getInvalidTempVarsInURLQuery,
|
||||
} from 'src/dashboards/utils/tempVars'
|
||||
import {stripTempVar} from 'src/dashboards/utils/tempVars'
|
||||
|
||||
import {dismissEditingAnnotation} from 'src/shared/actions/annotations'
|
||||
|
||||
|
@ -50,12 +45,7 @@ import {
|
|||
TEMP_VAR_UPPER_DASHBOARD_TIME,
|
||||
} from 'shared/constants'
|
||||
import {FORMAT_INFLUXQL, defaultTimeRange} from 'src/shared/data/timeRanges'
|
||||
import {validAbsoluteTimeRange} from 'src/dashboards/utils/time'
|
||||
import {
|
||||
notifyDashboardNotFound,
|
||||
notifyInvalidTempVarValueInURLQuery,
|
||||
notifyInvalidZoomedTimeRangeValueInURLQuery,
|
||||
} from 'shared/copy/notifications'
|
||||
|
||||
import {colorsStringSchema, colorsNumberSchema} from 'shared/schemas'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import {OverlayContext} from 'src/shared/components/OverlayTechnology'
|
||||
|
@ -65,22 +55,9 @@ class DashboardPage extends Component {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
let {zoomedLower, zoomedUpper} = urlQueries
|
||||
|
||||
if (!validAbsoluteTimeRange({lower: zoomedLower, upper: zoomedUpper})) {
|
||||
if (zoomedLower || zoomedUpper) {
|
||||
props.notify(notifyInvalidZoomedTimeRangeValueInURLQuery())
|
||||
}
|
||||
zoomedLower = null
|
||||
zoomedUpper = null
|
||||
}
|
||||
|
||||
this.state = {
|
||||
isEditMode: false,
|
||||
selectedCell: null,
|
||||
zoomedLower,
|
||||
zoomedUpper,
|
||||
scrollTop: 0,
|
||||
windowHeight: window.innerHeight,
|
||||
}
|
||||
|
@ -90,23 +67,18 @@ class DashboardPage extends Component {
|
|||
const {
|
||||
params: {dashboardID},
|
||||
dashboardActions: {
|
||||
getDashboardsAsync,
|
||||
hydrateTempVarValues,
|
||||
getDashboardWithHydratedAndSyncedTempVarsAsync,
|
||||
putDashboardByID,
|
||||
syncURLQueryFromTempVars,
|
||||
},
|
||||
source,
|
||||
meRole,
|
||||
isUsingAuth,
|
||||
router,
|
||||
notify,
|
||||
getAnnotationsAsync,
|
||||
timeRange,
|
||||
timeRange: {upper, lower},
|
||||
autoRefresh,
|
||||
location,
|
||||
} = this.props
|
||||
const {zoomedUpper, zoomedLower} = this.state
|
||||
|
||||
const annotationRange = millisecondTimeRange(timeRange)
|
||||
getAnnotationsAsync(source.links.annotations, annotationRange)
|
||||
|
@ -118,36 +90,19 @@ class DashboardPage extends Component {
|
|||
}
|
||||
|
||||
window.addEventListener('resize', this.handleWindowResize, true)
|
||||
const dashboards = await getDashboardsAsync()
|
||||
const dashboard = dashboards.find(
|
||||
d => d.id === idNormalizer(TYPE_ID, dashboardID)
|
||||
|
||||
await getDashboardWithHydratedAndSyncedTempVarsAsync(
|
||||
dashboardID,
|
||||
source,
|
||||
router,
|
||||
location
|
||||
)
|
||||
|
||||
if (!dashboard) {
|
||||
router.push(`/sources/${source.id}/dashboards`)
|
||||
return notify(notifyDashboardNotFound(dashboardID))
|
||||
}
|
||||
|
||||
const urlQueryTempVarsWithInvalidValues = getInvalidTempVarsInURLQuery(
|
||||
dashboard.templates
|
||||
)
|
||||
urlQueryTempVarsWithInvalidValues.forEach(invalidURLQuery => {
|
||||
notify(notifyInvalidTempVarValueInURLQuery(invalidURLQuery))
|
||||
})
|
||||
|
||||
syncURLQueryFromTempVars(location, dashboard.templates, [], {
|
||||
upper,
|
||||
lower,
|
||||
zoomedUpper,
|
||||
zoomedLower,
|
||||
})
|
||||
|
||||
// If using auth and role is Viewer, temp vars will be stale until dashboard
|
||||
// is refactored so as not to require a write operation (a PUT in this case)
|
||||
if (!isUsingAuth || isUserAuthorized(meRole, EDITOR_ROLE)) {
|
||||
// putDashboardByID refreshes & persists influxql generated template variable values.
|
||||
await putDashboardByID(dashboardID)
|
||||
await hydrateTempVarValues(source, dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,6 +252,7 @@ class DashboardPage extends Component {
|
|||
dashboardActions.deleteDashboardCellAsync(dashboard, cell)
|
||||
}
|
||||
|
||||
// TODO: make this a thunk
|
||||
handleSelectTemplate = templateID => value => {
|
||||
const {
|
||||
dashboardActions,
|
||||
|
@ -360,12 +316,9 @@ class DashboardPage extends Component {
|
|||
}
|
||||
|
||||
handleZoomedTimeRange = (zoomedLower, zoomedUpper) => {
|
||||
this.setState({zoomedLower, zoomedUpper})
|
||||
const {dashboardActions, location} = this.props
|
||||
dashboardActions.syncURLQueryFromQueriesObject(location, {
|
||||
zoomedLower,
|
||||
zoomedUpper,
|
||||
})
|
||||
const zoomedTimeRange = {zoomedLower, zoomedUpper}
|
||||
dashboardActions.setZoomedTimeRangeAsync(zoomedTimeRange, location)
|
||||
}
|
||||
|
||||
setScrollTop = event => {
|
||||
|
@ -380,6 +333,8 @@ class DashboardPage extends Component {
|
|||
sources,
|
||||
timeRange,
|
||||
timeRange: {lower, upper},
|
||||
zoomedTimeRange,
|
||||
zoomedTimeRange: {lower: zoomedLower, upper: zoomedUpper},
|
||||
showTemplateControlBar,
|
||||
dashboard,
|
||||
dashboards,
|
||||
|
@ -400,7 +355,6 @@ class DashboardPage extends Component {
|
|||
handleClickPresentationButton,
|
||||
params: {sourceID, dashboardID},
|
||||
} = this.props
|
||||
const {zoomedLower, zoomedUpper} = this.state
|
||||
|
||||
const low = zoomedLower || lower
|
||||
const up = zoomedUpper || upper
|
||||
|
@ -483,7 +437,7 @@ class DashboardPage extends Component {
|
|||
isHidden={inPresentationMode}
|
||||
onAddCell={this.handleAddCell}
|
||||
onManualRefresh={onManualRefresh}
|
||||
zoomedTimeRange={{zoomedUpper, zoomedLower}}
|
||||
zoomedTimeRange={zoomedTimeRange}
|
||||
onSave={this.handleRenameDashboard}
|
||||
onCancel={this.handleCancelEditDashboard}
|
||||
onEditDashboard={this.handleEditDashboard}
|
||||
|
@ -590,6 +544,10 @@ DashboardPage.propTypes = {
|
|||
upper: string,
|
||||
lower: string,
|
||||
}),
|
||||
zoomedTimeRange: shape({
|
||||
upper: string,
|
||||
lower: string,
|
||||
}),
|
||||
showTemplateControlBar: bool.isRequired,
|
||||
inPresentationMode: bool.isRequired,
|
||||
handleClickPresentationButton: func,
|
||||
|
@ -622,7 +580,7 @@ const mapStateToProps = (state, {params: {dashboardID}}) => {
|
|||
ephemeral: {inPresentationMode},
|
||||
persisted: {autoRefresh, showTemplateControlBar},
|
||||
},
|
||||
dashboardUI: {dashboards, cellQueryStatus},
|
||||
dashboardUI: {dashboards, cellQueryStatus, zoomedTimeRange},
|
||||
sources,
|
||||
dashTimeV1,
|
||||
auth: {me, isUsingAuth},
|
||||
|
@ -642,15 +600,10 @@ const mapStateToProps = (state, {params: {dashboardID}}) => {
|
|||
r => r.dashboardID === idNormalizer(TYPE_ID, dashboardID)
|
||||
) || defaultTimeRange
|
||||
|
||||
let dashboard = dashboards.find(
|
||||
const dashboard = dashboards.find(
|
||||
d => d.id === idNormalizer(TYPE_ID, dashboardID)
|
||||
)
|
||||
|
||||
if (dashboard) {
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
dashboard = applyDashboardTempVarOverrides(dashboard, urlQueries)
|
||||
}
|
||||
|
||||
const selectedCell = cell
|
||||
|
||||
return {
|
||||
|
@ -658,6 +611,7 @@ const mapStateToProps = (state, {params: {dashboardID}}) => {
|
|||
meRole,
|
||||
dashboard,
|
||||
timeRange,
|
||||
zoomedTimeRange,
|
||||
dashboards,
|
||||
autoRefresh,
|
||||
isUsingAuth,
|
||||
|
|
|
@ -9,6 +9,7 @@ const {lower, upper} = timeRanges.find(tr => tr.lower === 'now() - 1h')
|
|||
const initialState = {
|
||||
dashboards: [],
|
||||
timeRange: {lower, upper},
|
||||
zoomedTimeRange: {lower: null, upper: null},
|
||||
isEditMode: false,
|
||||
cellQueryStatus: {queryID: null, status: null},
|
||||
hoverTime: NULL_HOVER_TIME,
|
||||
|
@ -29,12 +30,25 @@ export default function ui(state = initialState, action) {
|
|||
return {...state, ...newState}
|
||||
}
|
||||
|
||||
case 'LOAD_DASHBOARD': {
|
||||
const {dashboard} = action.payload
|
||||
const newDashboards = _.unionBy([dashboard], state.dashboards, 'id')
|
||||
|
||||
return {...state, dashboards: newDashboards}
|
||||
}
|
||||
|
||||
case 'SET_DASHBOARD_TIME_RANGE': {
|
||||
const {timeRange} = action.payload
|
||||
|
||||
return {...state, timeRange}
|
||||
}
|
||||
|
||||
case 'SET_DASHBOARD_ZOOMED_TIME_RANGE': {
|
||||
const {zoomedTimeRange} = action.payload
|
||||
|
||||
return {...state, zoomedTimeRange}
|
||||
}
|
||||
|
||||
case 'UPDATE_DASHBOARD': {
|
||||
const {dashboard} = action.payload
|
||||
const newState = {
|
||||
|
@ -235,12 +249,12 @@ export default function ui(state = initialState, action) {
|
|||
}
|
||||
|
||||
case 'TEMPLATE_VARIABLES_SELECTED_BY_NAME': {
|
||||
const {dashboardID, query} = action.payload
|
||||
const {dashboardID, queries} = action.payload
|
||||
|
||||
const newDashboards = state.dashboards.map(
|
||||
oldDashboard =>
|
||||
oldDashboard.id === dashboardID
|
||||
? applyDashboardTempVarOverrides(oldDashboard, query)
|
||||
? applyDashboardTempVarOverrides(oldDashboard, queries)
|
||||
: oldDashboard
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import _ from 'lodash'
|
||||
import queryString from 'query-string'
|
||||
|
||||
import {TEMPLATE_VARIABLE_QUERIES} from 'src/dashboards/constants'
|
||||
|
||||
|
@ -124,9 +123,7 @@ export const applyDashboardTempVarOverrides = (
|
|||
),
|
||||
})
|
||||
|
||||
export const getInvalidTempVarsInURLQuery = tempVars => {
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
|
||||
export const findInvalidTempVarsInURLQuery = (tempVars, urlQueries) => {
|
||||
const urlQueryTempVarsWithInvalidValues = _.reduce(
|
||||
urlQueries,
|
||||
(acc, v, k) => {
|
||||
|
|
|
@ -2,59 +2,12 @@
|
|||
import queryString from 'query-string'
|
||||
|
||||
import {enablePresentationMode} from 'src/shared/actions/app'
|
||||
import {setDashTimeV1} from 'src/dashboards/actions'
|
||||
import {notify as notifyAction} from 'shared/actions/notifications'
|
||||
import {notifyInvalidTimeRangeValueInURLQuery} from 'shared/copy/notifications'
|
||||
import {defaultTimeRange} from 'src/shared/data/timeRanges'
|
||||
import idNormalizer, {TYPE_ID} from 'src/normalizers/id'
|
||||
import {validTimeRange} from 'src/dashboards/utils/time'
|
||||
|
||||
export const queryStringConfig = store => {
|
||||
let prevPath
|
||||
return dispatch => action => {
|
||||
dispatch(action)
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
export const queryStringConfig = () => dispatch => action => {
|
||||
dispatch(action)
|
||||
const urlQueries = queryString.parse(window.location.search)
|
||||
|
||||
// Presentation Mode
|
||||
if (urlQueries.present === 'true') {
|
||||
dispatch(enablePresentationMode())
|
||||
}
|
||||
|
||||
const dashboardRegex = /\/sources\/\d+\/dashboards\/(\d+)/
|
||||
if (dashboardRegex.test(window.location.pathname)) {
|
||||
const currentPath = window.location.pathname
|
||||
const dashboardID = currentPath.match(dashboardRegex)[1]
|
||||
if (currentPath !== prevPath) {
|
||||
let timeRange
|
||||
const {dashTimeV1} = store.getState()
|
||||
|
||||
const timeRangeFromQueries = {
|
||||
upper: urlQueries.upper,
|
||||
lower: urlQueries.lower,
|
||||
}
|
||||
const timeRangeOrNull = validTimeRange(timeRangeFromQueries)
|
||||
|
||||
if (timeRangeOrNull) {
|
||||
timeRange = timeRangeOrNull
|
||||
} else {
|
||||
const dashboardTimeRange = dashTimeV1.ranges.find(
|
||||
r => r.dashboardID === idNormalizer(TYPE_ID, dashboardID)
|
||||
)
|
||||
|
||||
timeRange = dashboardTimeRange || defaultTimeRange
|
||||
|
||||
if (timeRangeFromQueries.lower || timeRangeFromQueries.upper) {
|
||||
dispatch(
|
||||
notifyAction(
|
||||
notifyInvalidTimeRangeValueInURLQuery(timeRangeFromQueries)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(setDashTimeV1(+dashboardID, timeRange))
|
||||
}
|
||||
prevPath = currentPath
|
||||
}
|
||||
if (urlQueries.present === 'true') {
|
||||
dispatch(enablePresentationMode())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue