Merge branch 'master' into dropdown-autocomplete
commit
39754aa28a
|
@ -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
|
||||
|
|
|
@ -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{},
|
||||
|
|
|
@ -43,7 +43,7 @@ const VisView = ({
|
|||
if (cellType === 'single-stat') {
|
||||
return (
|
||||
<RefreshingSingleStat
|
||||
queries={[queries[0]]}
|
||||
queries={queries.length ? [queries[0]] : []}
|
||||
autoRefresh={autoRefresh}
|
||||
templates={templates}
|
||||
/>
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export const errorThrown = (error, altText) => ({
|
||||
export const errorThrown = (error, altText, alertType) => ({
|
||||
type: 'ERROR_THROWN',
|
||||
error,
|
||||
altText,
|
||||
alertType,
|
||||
})
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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.'))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue