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
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. [#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. [#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
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. [#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
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
}
if itsDashboardTime {
influxQL = strings.Replace(influxQL, "now() - 15m", ":dashboardTime:", 1)
}
raw := chronograf.QueryConfig{
RawText: &influxQL,
Fields: []chronograf.Field{},

View File

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

View File

@ -40,6 +40,8 @@ import 'src/style/chronograf.scss'
import {HEARTBEAT_INTERVAL} from 'shared/constants'
const errorsQueue = []
const rootNode = document.getElementById('react-root')
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
})
const store = configureStore(loadLocalStorage(), browserHistory)
const store = configureStore(loadLocalStorage(errorsQueue), browserHistory)
const {dispatch} = store
browserHistory.listen(() => {
@ -67,6 +69,7 @@ const history = syncHistoryWithStore(browserHistory, store)
const Root = React.createClass({
componentWillMount() {
this.flushErrorsQueue()
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() {
return (
<Provider store={store}>

View File

@ -1,10 +1,30 @@
export const loadLocalStorage = () => {
export const loadLocalStorage = errorsQueue => {
try {
const serializedState = localStorage.getItem('state')
return JSON.parse(serializedState) || {}
} catch (err) {
console.error(`Loading persisted state failed: ${err}`) // eslint-disable-line no-console
const state = JSON.parse(serializedState)
// 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 {}
}
}
@ -25,6 +45,7 @@ export const saveToLocalStorage = ({
queryConfigs,
timeRange,
dataExplorer,
VERSION, // eslint-disable-line no-undef
})
)
} catch (err) {

View File

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

View File

@ -32,7 +32,7 @@ export const handleSuccess = (data, 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
editQueryStatus(query.id, {error: message})

View File

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