Merge branch 'master' into dropdown-autocomplete

pull/1500/head
Alex Paxton 2017-05-18 12:46:59 -07:00 committed by GitHub
commit 39754aa28a
8 changed files with 53 additions and 13 deletions

View File

@ -2,15 +2,18 @@
### Bug Fixes ### Bug Fixes
1. [#1450](https://github.com/influxdata/chronograf/pull/1450): Fix infinite spinner when using "/chronograf" as a basepath 1. [#1450](https://github.com/influxdata/chronograf/pull/1450): Fix infinite spinner when using "/chronograf" as a basepath
1. [#1458](https://github.com/influxdata/chronograf/pull/1458): New versions of Chronograf will automatically clear localStorage settings until further notice.
1. [#1455](https://github.com/influxdata/chronograf/issues/1455): Fix backwards sort arrows in tables 1. [#1455](https://github.com/influxdata/chronograf/issues/1455): Fix backwards sort arrows in tables
1. [#1423](https://github.com/influxdata/chronograf/issues/1423): Make logout nav item consistent with design 1. [#1423](https://github.com/influxdata/chronograf/issues/1423): Make logout nav item consistent with design
1. [#1426](https://github.com/influxdata/chronograf/issues/1426): Fix graph loading spinner 1. [#1426](https://github.com/influxdata/chronograf/issues/1426): Fix graph loading spinner
1. [#1485](https://github.com/influxdata/chronograf/issues/1485): Filter out any template variable values that are empty, whitespace, or duplicates 1. [#1485](https://github.com/influxdata/chronograf/pull/1485): Filter out any template variable values that are empty, whitespace, or duplicates
1. [#1484](https://github.com/influxdata/chronograf/pull/1484): Allow user to select SingleStat as Visualization Type before adding any queries and continue to be able to click Add Query
### Features ### Features
1. [#1477](https://github.com/influxdata/chronograf/pull/1477): Add ability to log alerts 1. [#1477](https://github.com/influxdata/chronograf/pull/1477): Add ability to log alerts
1. [#1491](https://github.com/influxdata/chronograf/pull/1491): Update go vendoring to dep and committed vendor directory 1. [#1491](https://github.com/influxdata/chronograf/pull/1491): Update go vendoring to dep and committed vendor directory
1. [#1500](https://github.com/influxdata/chronograf/pull/1500): Add autocomplete functionality to Template Variable dropdowns 1. [#1500](https://github.com/influxdata/chronograf/pull/1500): Add autocomplete functionality to Template Variable dropdowns
1. [#1498](https://github.com/influxdata/chronograf/pull/1498): Notify user via UI when local settings are cleared
### UI Improvements ### UI Improvements
1. [#1451](https://github.com/influxdata/chronograf/pull/1451): Refactor scrollbars to support non-webkit browsers 1. [#1451](https://github.com/influxdata/chronograf/pull/1451): Refactor scrollbars to support non-webkit browsers

View File

@ -21,6 +21,10 @@ func Convert(influxQL string) (chronograf.QueryConfig, error) {
return chronograf.QueryConfig{}, err return chronograf.QueryConfig{}, err
} }
if itsDashboardTime {
influxQL = strings.Replace(influxQL, "now() - 15m", ":dashboardTime:", 1)
}
raw := chronograf.QueryConfig{ raw := chronograf.QueryConfig{
RawText: &influxQL, RawText: &influxQL,
Fields: []chronograf.Field{}, Fields: []chronograf.Field{},

View File

@ -43,7 +43,7 @@ const VisView = ({
if (cellType === 'single-stat') { if (cellType === 'single-stat') {
return ( return (
<RefreshingSingleStat <RefreshingSingleStat
queries={[queries[0]]} queries={queries.length ? [queries[0]] : []}
autoRefresh={autoRefresh} autoRefresh={autoRefresh}
templates={templates} templates={templates}
/> />

View File

@ -40,6 +40,8 @@ import 'src/style/chronograf.scss'
import {HEARTBEAT_INTERVAL} from 'shared/constants' import {HEARTBEAT_INTERVAL} from 'shared/constants'
const errorsQueue = []
const rootNode = document.getElementById('react-root') const rootNode = document.getElementById('react-root')
const basepath = rootNode.dataset.basepath || '' const basepath = rootNode.dataset.basepath || ''
@ -48,7 +50,7 @@ const browserHistory = useRouterHistory(createHistory)({
basename: basepath, // this is written in when available by the URL prefixer middleware basename: basepath, // this is written in when available by the URL prefixer middleware
}) })
const store = configureStore(loadLocalStorage(), browserHistory) const store = configureStore(loadLocalStorage(errorsQueue), browserHistory)
const {dispatch} = store const {dispatch} = store
browserHistory.listen(() => { browserHistory.listen(() => {
@ -67,6 +69,7 @@ const history = syncHistoryWithStore(browserHistory, store)
const Root = React.createClass({ const Root = React.createClass({
componentWillMount() { componentWillMount() {
this.flushErrorsQueue()
this.checkAuth() this.checkAuth()
}, },
@ -99,6 +102,14 @@ const Root = React.createClass({
} }
}, },
flushErrorsQueue() {
if (errorsQueue.length) {
errorsQueue.forEach(errorText => {
dispatch(errorThrown({status: 0, auth: null}, errorText, 'warning'))
})
}
},
render() { render() {
return ( return (
<Provider store={store}> <Provider store={store}>

View File

@ -1,10 +1,30 @@
export const loadLocalStorage = () => { export const loadLocalStorage = errorsQueue => {
try { try {
const serializedState = localStorage.getItem('state') const serializedState = localStorage.getItem('state')
return JSON.parse(serializedState) || {} const state = JSON.parse(serializedState)
} catch (err) {
console.error(`Loading persisted state failed: ${err}`) // eslint-disable-line no-console // eslint-disable-next-line no-undef
if (state.VERSION !== VERSION) {
const errorText =
'New version of Chronograf detected. Local settings cleared.'
console.log(errorText) // eslint-disable-line no-console
errorsQueue.push(errorText)
window.localStorage.removeItem('state')
return {}
}
delete state.VERSION
return state || {}
} catch (error) {
const errorText = `Loading local settings failed: ${error}`
console.error(errorText) // eslint-disable-line no-console
errorsQueue.push(errorText)
return {} return {}
} }
} }
@ -25,6 +45,7 @@ export const saveToLocalStorage = ({
queryConfigs, queryConfigs,
timeRange, timeRange,
dataExplorer, dataExplorer,
VERSION, // eslint-disable-line no-undef
}) })
) )
} catch (err) { } catch (err) {

View File

@ -1,5 +1,6 @@
export const errorThrown = (error, altText) => ({ export const errorThrown = (error, altText, alertType) => ({
type: 'ERROR_THROWN', type: 'ERROR_THROWN',
error, error,
altText, altText,
alertType,
}) })

View File

@ -32,7 +32,7 @@ export const handleSuccess = (data, query, editQueryStatus) => {
} }
export const handleError = (error, query, editQueryStatus) => { export const handleError = (error, query, editQueryStatus) => {
const message = _.get(error, ['data', 'message'], error) const message = _.get(error, ['data', 'message'], error.toString())
// 400 from chrono server = fail // 400 from chrono server = fail
editQueryStatus(query.id, {error: message}) editQueryStatus(query.id, {error: message})

View File

@ -17,7 +17,7 @@ const errorsMiddleware = store => next => action => {
const {auth: {me}} = store.getState() const {auth: {me}} = store.getState()
if (action.type === 'ERROR_THROWN') { if (action.type === 'ERROR_THROWN') {
const {error: {status, auth}, altText} = action const {error: {status, auth}, altText, alertType = 'error'} = action
if (status === HTTP_FORBIDDEN) { if (status === HTTP_FORBIDDEN) {
const wasSessionTimeout = me !== null const wasSessionTimeout = me !== null
@ -26,7 +26,7 @@ const errorsMiddleware = store => next => action => {
if (wasSessionTimeout) { if (wasSessionTimeout) {
store.dispatch( store.dispatch(
notify('error', 'Session timed out. Please login again.') notify(alertType, 'Session timed out. Please login again.')
) )
allowNotifications = false allowNotifications = false
@ -35,9 +35,9 @@ const errorsMiddleware = store => next => action => {
}, notificationsBlackoutDuration) }, notificationsBlackoutDuration)
} }
} else if (altText) { } else if (altText) {
store.dispatch(notify('error', altText)) store.dispatch(notify(alertType, altText))
} else { } else {
store.dispatch(notify('error', 'Cannot communicate with server.')) store.dispatch(notify(alertType, 'Cannot communicate with server.'))
} }
} }