Merge pull request #5888 from influxdata/fix/show_queries_error

fix(ui): show failure reason on queries page
pull/5893/head
Pavel Závora 2022-03-18 13:32:36 +01:00 committed by GitHub
commit a622546c56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 52 deletions

View File

@ -21,6 +21,7 @@
1. [#5878](https://github.com/influxdata/chronograf/pull/5878): Rename Flux Query to Flux Script. 1. [#5878](https://github.com/influxdata/chronograf/pull/5878): Rename Flux Query to Flux Script.
1. [#5885](https://github.com/influxdata/chronograf/pull/5885): Repair time zone selector on Host page. 1. [#5885](https://github.com/influxdata/chronograf/pull/5885): Repair time zone selector on Host page.
1. [#5886](https://github.com/influxdata/chronograf/pull/5886): Report correct chronograf version. 1. [#5886](https://github.com/influxdata/chronograf/pull/5886): Report correct chronograf version.
1. [#5888](https://github.com/influxdata/chronograf/pull/5888): Show failure reason on Queries page.
### Other ### Other

View File

@ -25,12 +25,14 @@ import {
import {notify as notifyAction} from 'shared/actions/notifications' import {notify as notifyAction} from 'shared/actions/notifications'
import {Button, IconFont, ComponentStatus} from 'src/reusable_ui' import {Button, IconFont, ComponentStatus} from 'src/reusable_ui'
import moment from 'moment' import moment from 'moment'
import FormElementError from 'src/reusable_ui/components/form_layout/FormElementError'
class QueriesPage extends Component { class QueriesPage extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
updateInterval: 5000, updateInterval: 5000,
errors: [],
} }
} }
componentDidMount() { componentDidMount() {
@ -51,22 +53,24 @@ class QueriesPage extends Component {
render() { render() {
const {queries, queriesSort, changeSort} = this.props const {queries, queriesSort, changeSort} = this.props
const {updateInterval, title} = this.state const {updateInterval, title, errors} = this.state
return ( return (
<div className="panel panel-solid"> <div className="panel panel-solid">
<div className="panel-heading"> <div className="panel-heading">
<h2 className="panel-title">{title}</h2> <h2 className="panel-title">{title}</h2>
<div style={{float: 'right', display: 'flex'}}> <div style={{float: 'right', display: 'flex'}}>
<div style={{marginRight: '5px'}}> {queries && queries.length ? (
<Button <div style={{marginRight: '5px'}}>
customClass="csv-export" <Button
text="CSV" customClass="csv-export"
icon={IconFont.Download} text="CSV"
status={ComponentStatus.Default} icon={IconFont.Download}
onClick={this.downloadCSV} status={ComponentStatus.Default}
/> onClick={this.downloadCSV}
</div> />
</div>
) : null}
<AutoRefreshDropdown <AutoRefreshDropdown
selected={updateInterval} selected={updateInterval}
onChoose={this.changeRefreshInterval} onChoose={this.changeRefreshInterval}
@ -76,12 +80,23 @@ class QueriesPage extends Component {
</div> </div>
</div> </div>
<div className="panel-body"> <div className="panel-body">
<QueriesTable {queries && queries.length ? (
queries={queries} <QueriesTable
queriesSort={queriesSort} queries={queries}
changeSort={changeSort} queriesSort={queriesSort}
onKillQuery={this.handleKillQuery} changeSort={changeSort}
/> onKillQuery={this.handleKillQuery}
/>
) : null}
{errors.length ? (
<div style={{marginTop: '5px'}}>
{errors.map((e, i) => (
<div key={`error${i}`}>
<FormElementError message={e} />
</div>
))}
</div>
) : null}
</div> </div>
</div> </div>
) )
@ -89,47 +104,57 @@ class QueriesPage extends Component {
updateQueries = () => { updateQueries = () => {
const {source, notify, loadQueries} = this.props const {source, notify, loadQueries} = this.props
showDatabases(source.links.proxy).then(resp => { const dbErrors = []
const {databases, errors} = showDatabasesParser(resp.data) showDatabases(source.links.proxy)
if (errors.length) { .then(resp => {
this.setState(state => ({...state, title: ''})) const {databases, errors} = showDatabasesParser(resp.data)
errors.forEach(message => notify(notifyQueriesError(message))) if (errors.length) {
return this.setState(state => ({...state, title: ''}))
} errors.forEach(message => notify(notifyQueriesError(message)))
this.setState(state => ({ return
...state, }
title: this.setState(state => ({
databases.length === 1 ...state,
? '1 Database' title:
: `${databases.length} Databases`, databases.length === 1
})) ? '1 Database'
: `${databases.length} Databases`,
}))
const fetches = databases.map(db => showQueries(source.links.proxy, db)) const fetches = databases.map(db => showQueries(source.links.proxy, db))
Promise.allSettled(fetches).then(results => { return Promise.allSettled(fetches).then(results => {
const allQueries = [] const allQueries = []
results.forEach((settledResponse, i) => { results.forEach((settledResponse, i) => {
if (!settledResponse.value) { if (!settledResponse.value) {
console.error( const msg = `Unable to show queries on '${databases[i]}': ${settledResponse.reason}`
`Unable to show queries on '${databases[i]}': `, dbErrors.push(msg)
settledResponse.reason console.error(
) 'Unable to show queries',
return databases[i],
} settledResponse.reason
const result = showQueriesParser(settledResponse.value.data) )
if (result.errors.length) { return
result.errors.forEach(message => }
notify(notifyQueriesError(message)) const result = showQueriesParser(settledResponse.value.data)
) if (result.errors.length) {
} result.errors.forEach(message =>
notify(notifyQueriesError(message))
)
}
allQueries.push(...result.queries) allQueries.push(...result.queries)
})
const queries = uniqBy(flatten(allQueries), q => q.id)
loadQueries(queries)
}) })
const queries = uniqBy(flatten(allQueries), q => q.id)
loadQueries(queries)
}) })
}) .catch(e => {
dbErrors.push(`Unable to show databases: ${e}`)
console.error('Unable to show databases', e)
})
.then(() => this.setState({errors: dbErrors}))
} }
changeRefreshInterval = ({milliseconds: updateInterval}) => { changeRefreshInterval = ({milliseconds: updateInterval}) => {
this.setState(state => ({...state, updateInterval})) this.setState(state => ({...state, updateInterval}))