From 6c3d1668bfa8db843920e2dac186b4d743893643 Mon Sep 17 00:00:00 2001 From: Hunter Trujillo Date: Tue, 5 Sep 2017 17:57:52 -0600 Subject: [PATCH 1/4] Refactor query string middleware. Adds novel DE query config functionality. --- ui/src/dashboards/actions/index.js | 4 -- ui/src/dashboards/containers/DashboardPage.js | 3 -- ui/src/data_explorer/actions/view/index.js | 1 + ui/src/shared/middleware/queryStringConfig.js | 52 +++++++++++++++++++ ui/src/shared/middleware/resizeLayout.js | 31 ++++------- ui/src/store/configureStore.js | 4 +- 6 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 ui/src/shared/middleware/queryStringConfig.js diff --git a/ui/src/dashboards/actions/index.js b/ui/src/dashboards/actions/index.js index 0675b0f8e..24eca86ed 100644 --- a/ui/src/dashboards/actions/index.js +++ b/ui/src/dashboards/actions/index.js @@ -265,7 +265,3 @@ export const updateTempVarValues = (source, dashboard) => async dispatch => { dispatch(errorThrown(error)) } } - -export const selectTempVarsFromUrl = (dashboardID, query = {}) => dispatch => { - dispatch(templateVariablesSelectedByName(dashboardID, query)) -} diff --git a/ui/src/dashboards/containers/DashboardPage.js b/ui/src/dashboards/containers/DashboardPage.js index e93d3e1ca..ff54a7522 100644 --- a/ui/src/dashboards/containers/DashboardPage.js +++ b/ui/src/dashboards/containers/DashboardPage.js @@ -41,11 +41,9 @@ class DashboardPage extends Component { dashboardActions: { getDashboardsAsync, updateTempVarValues, - selectTempVarsFromUrl, putDashboardByID, }, source, - location: {query}, } = this.props const dashboards = await getDashboardsAsync() @@ -53,7 +51,6 @@ class DashboardPage extends Component { // Refresh and persists influxql generated template variable values await updateTempVarValues(source, dashboard) - selectTempVarsFromUrl(+dashboardID, query) await putDashboardByID(dashboardID) } diff --git a/ui/src/data_explorer/actions/view/index.js b/ui/src/data_explorer/actions/view/index.js index ce8971ea9..68c5d6af1 100644 --- a/ui/src/data_explorer/actions/view/index.js +++ b/ui/src/data_explorer/actions/view/index.js @@ -138,6 +138,7 @@ export const editRawTextAsync = (url, id, text) => async dispatch => { try { const {data} = await getQueryConfig(url, [{query: text, id}]) const config = data.queries.find(q => q.id === id) + config.queryConfig.rawText = text dispatch(updateQueryConfig(config.queryConfig)) } catch (error) { dispatch(errorThrown(error)) diff --git a/ui/src/shared/middleware/queryStringConfig.js b/ui/src/shared/middleware/queryStringConfig.js new file mode 100644 index 000000000..10f755fd4 --- /dev/null +++ b/ui/src/shared/middleware/queryStringConfig.js @@ -0,0 +1,52 @@ +// Middleware generally used for actions needing parsed queryStrings +import queryString from 'query-string' +import uuid from 'node-uuid' + +import {enablePresentationMode} from 'src/shared/actions/app' +import {editRawTextAsync} from 'src/data_explorer/actions/view' +import {templateVariablesSelectedByName} from 'src/dashboards/actions' + +export const queryStringConfig = store => next => action => { + next(action) + const qs = queryString.parse(window.location.search) + + // Presentation Mode + if (qs.present === 'true') { + next(enablePresentationMode()) + } + + // Data Explorer Query Config + if (qs.query) { + const query = decodeURIComponent(qs.query) + const state = store.getState() + const defaultSource = state.sources.find(source => source.default) + let id = window.location.hash // Stored on hash to prevent page reload + + if (defaultSource && !id) { + // Find query by raw text + for (const qid in state.dataExplorerQueryConfigs) { + const qc = state.dataExplorerQueryConfigs[qid] + if (qc && qc.rawText === query) { + id = qid + } + } + + id = id || uuid.v4() + + qs.queryID = id + window.location.hash = id + } + + if (defaultSource && !state.dataExplorerQueryConfigs[id]) { + const url = defaultSource.links.queries + editRawTextAsync(url, id, query)(next) + } + } + + // Select Template Variable By Name + const dashboardRegex = /\/sources\/(\d+?)\/dashboards\/(\d+?)/ + if (dashboardRegex.test(window.location.pathname)) { + const dashboardID = window.location.pathname.match(dashboardRegex)[2] + next(templateVariablesSelectedByName(+dashboardID, qs)) + } +} diff --git a/ui/src/shared/middleware/resizeLayout.js b/ui/src/shared/middleware/resizeLayout.js index 6af500579..f551bb233 100644 --- a/ui/src/shared/middleware/resizeLayout.js +++ b/ui/src/shared/middleware/resizeLayout.js @@ -1,25 +1,14 @@ // Trigger resize event to relayout the React Layout plugin -import queryString from 'query-string' -import {enablePresentationMode} from 'src/shared/actions/app' +export const resizeLayout = () => next => action => { + next(action) -export default function resizeLayout() { - return next => action => { - next(action) - if ( - action.type === 'ENABLE_PRESENTATION_MODE' || - action.type === 'DISABLE_PRESENTATION_MODE' - ) { - // Uses longer event object creation method due to IE compatibility. - const evt = document.createEvent('HTMLEvents') - evt.initEvent('resize', false, true) - window.dispatchEvent(evt) - } - - const qs = queryString.parse(window.location.search) - - if (qs.present === 'true') { - next(enablePresentationMode()) - next(action) - } + if ( + action.type === 'ENABLE_PRESENTATION_MODE' || + action.type === 'DISABLE_PRESENTATION_MODE' + ) { + // Uses longer event object creation method due to IE compatibility. + const evt = document.createEvent('HTMLEvents') + evt.initEvent('resize', false, true) + window.dispatchEvent(evt) } } diff --git a/ui/src/store/configureStore.js b/ui/src/store/configureStore.js index d065d0232..11a876b3d 100644 --- a/ui/src/store/configureStore.js +++ b/ui/src/store/configureStore.js @@ -4,7 +4,8 @@ import {routerReducer, routerMiddleware} from 'react-router-redux' import thunkMiddleware from 'redux-thunk' import errorsMiddleware from 'shared/middleware/errors' -import resizeLayout from 'shared/middleware/resizeLayout' +import {resizeLayout} from 'shared/middleware/resizeLayout' +import {queryStringConfig} from 'shared/middleware/queryStringConfig' import statusReducers from 'src/status/reducers' import sharedReducers from 'shared/reducers' import dataExplorerReducers from 'src/data_explorer/reducers' @@ -33,6 +34,7 @@ export default function configureStore(initialState, browserHistory) { thunkMiddleware, routingMiddleware, errorsMiddleware, + queryStringConfig, resizeLayout ) )(createStore) From edc4ccbdc4c14f7e053e24dec2adc389ef35b0eb Mon Sep 17 00:00:00 2001 From: Hunter Trujillo Date: Tue, 5 Sep 2017 18:12:48 -0600 Subject: [PATCH 2/4] Changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e82eeb1fb..146d83414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,14 @@ 1. [#1943](https://github.com/influxdata/chronograf/pull/1943): Fix inability to add kapacitor from source page on fresh install 1. [#1947](https://github.com/influxdata/chronograf/pull/1947): Fix DataExplorer crash if field property not present on queryConfig 1. [#1957](https://github.com/influxdata/chronograf/pull/1957): Fix stacked graphs not being fully displayed +1. [#1969](https://github.com/influxdata/chronograf/pull/1969): Fix for delayed selection of template variables using URL query params ### Features 1. [#1928](https://github.com/influxdata/chronograf/pull/1928): Add prefix, suffix, scale, and other y-axis formatting 1. [#1886](https://github.com/influxdata/chronograf/pull/1886): Fix limit of 100 alert rules on alert rules page 1. [#1934](https://github.com/influxdata/chronograf/pull/1943): Zoom syncronization and enhancement 1. [#1945](https://github.com/influxdata/chronograf/pull/1945): Add `present` boolean query param to URL to enable presentation mode +1. [#1969](https://github.com/influxdata/chronograf/pull/1969): Add `query` query param to URL to add a query to the Data Explorer ### UI Improvements 1. [#1933](https://github.com/influxdata/chronograf/pull/1933): Use line-stacked graph type for memory information - thank you, @Joxit! From 3764d4d650cd7b1d414b5261ecdc0843c56c27b0 Mon Sep 17 00:00:00 2001 From: Hunter Trujillo Date: Wed, 6 Sep 2017 11:50:02 -0600 Subject: [PATCH 3/4] Remove DE QC query string param code for this PR. --- ui/src/shared/middleware/queryStringConfig.js | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/ui/src/shared/middleware/queryStringConfig.js b/ui/src/shared/middleware/queryStringConfig.js index 10f755fd4..bdd3d464d 100644 --- a/ui/src/shared/middleware/queryStringConfig.js +++ b/ui/src/shared/middleware/queryStringConfig.js @@ -15,34 +15,6 @@ export const queryStringConfig = store => next => action => { next(enablePresentationMode()) } - // Data Explorer Query Config - if (qs.query) { - const query = decodeURIComponent(qs.query) - const state = store.getState() - const defaultSource = state.sources.find(source => source.default) - let id = window.location.hash // Stored on hash to prevent page reload - - if (defaultSource && !id) { - // Find query by raw text - for (const qid in state.dataExplorerQueryConfigs) { - const qc = state.dataExplorerQueryConfigs[qid] - if (qc && qc.rawText === query) { - id = qid - } - } - - id = id || uuid.v4() - - qs.queryID = id - window.location.hash = id - } - - if (defaultSource && !state.dataExplorerQueryConfigs[id]) { - const url = defaultSource.links.queries - editRawTextAsync(url, id, query)(next) - } - } - // Select Template Variable By Name const dashboardRegex = /\/sources\/(\d+?)\/dashboards\/(\d+?)/ if (dashboardRegex.test(window.location.pathname)) { From 147abd76d94b3914e692441fdd5ca0eeb50b6600 Mon Sep 17 00:00:00 2001 From: Hunter Trujillo Date: Wed, 6 Sep 2017 11:56:04 -0600 Subject: [PATCH 4/4] whoops! forgot my hat. --- ui/src/shared/middleware/queryStringConfig.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/src/shared/middleware/queryStringConfig.js b/ui/src/shared/middleware/queryStringConfig.js index bdd3d464d..0dfac5a57 100644 --- a/ui/src/shared/middleware/queryStringConfig.js +++ b/ui/src/shared/middleware/queryStringConfig.js @@ -1,12 +1,10 @@ // Middleware generally used for actions needing parsed queryStrings import queryString from 'query-string' -import uuid from 'node-uuid' import {enablePresentationMode} from 'src/shared/actions/app' -import {editRawTextAsync} from 'src/data_explorer/actions/view' import {templateVariablesSelectedByName} from 'src/dashboards/actions' -export const queryStringConfig = store => next => action => { +export const queryStringConfig = () => next => action => { next(action) const qs = queryString.parse(window.location.search)