Replace addFlashMessage with publishNotification
Also refactoring App.js into a SFCpull/10616/head
parent
9f85542d19
commit
a14f860ef1
|
@ -1,43 +1,20 @@
|
|||
import React, {Component} from 'react'
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import SideNav from 'src/side_nav'
|
||||
import Notifications from 'shared/components/Notifications'
|
||||
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
const App = ({children}) =>
|
||||
<div className="chronograf-root">
|
||||
<Notifications />
|
||||
<SideNav />
|
||||
{children}
|
||||
</div>
|
||||
|
||||
class App extends Component {
|
||||
notify = notification => {
|
||||
const {publishNotification} = this.props
|
||||
|
||||
publishNotification(notification)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="chronograf-root">
|
||||
<Notifications />
|
||||
<SideNav />
|
||||
{this.props.children &&
|
||||
React.cloneElement(this.props.children, {
|
||||
addFlashMessage: this.notify,
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {func, node} = PropTypes
|
||||
const {node} = PropTypes
|
||||
|
||||
App.propTypes = {
|
||||
children: node.isRequired,
|
||||
publishNotification: func.isRequired,
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(App)
|
||||
export default App
|
||||
|
|
|
@ -12,6 +12,7 @@ import ManualRefresh from 'src/shared/components/ManualRefresh'
|
|||
import {getCpuAndLoadForHosts, getLayouts, getAppsForHosts} from '../apis'
|
||||
import {getEnv} from 'src/shared/apis/env'
|
||||
import {setAutoRefresh} from 'shared/actions/app'
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
class HostsPage extends Component {
|
||||
constructor(props) {
|
||||
|
@ -25,7 +26,7 @@ class HostsPage extends Component {
|
|||
}
|
||||
|
||||
async fetchHostsData() {
|
||||
const {source, links, addFlashMessage} = this.props
|
||||
const {source, links, publishNotification} = this.props
|
||||
const {telegrafSystemInterval} = await getEnv(links.environment)
|
||||
const hostsError = 'Unable to get hosts'
|
||||
try {
|
||||
|
@ -51,7 +52,12 @@ class HostsPage extends Component {
|
|||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
addFlashMessage({type: 'error', text: hostsError})
|
||||
publishNotification({
|
||||
icon: 'alert-triangle',
|
||||
type: 'danger',
|
||||
duration: 5000,
|
||||
message: hostsError,
|
||||
})
|
||||
this.setState({
|
||||
hostsError,
|
||||
hostsLoading: false,
|
||||
|
@ -60,14 +66,19 @@ class HostsPage extends Component {
|
|||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const {addFlashMessage, autoRefresh} = this.props
|
||||
const {publishNotification, autoRefresh} = this.props
|
||||
|
||||
this.setState({hostsLoading: true}) // Only print this once
|
||||
const {data} = await getLayouts()
|
||||
this.layouts = data.layouts
|
||||
if (!this.layouts) {
|
||||
const layoutError = 'Unable to get apps for hosts'
|
||||
addFlashMessage({type: 'error', text: layoutError})
|
||||
publishNotification({
|
||||
icon: 'alert-triangle',
|
||||
type: 'danger',
|
||||
duration: 5000,
|
||||
message: layoutError,
|
||||
})
|
||||
this.setState({
|
||||
hostsError: layoutError,
|
||||
hostsLoading: false,
|
||||
|
@ -169,11 +180,11 @@ HostsPage.propTypes = {
|
|||
links: shape({
|
||||
environment: string.isRequired,
|
||||
}),
|
||||
addFlashMessage: func,
|
||||
autoRefresh: number.isRequired,
|
||||
manualRefresh: number,
|
||||
onChooseAutoRefresh: func.isRequired,
|
||||
onManualRefresh: func.isRequired,
|
||||
publishNotification: func.isRequired,
|
||||
}
|
||||
|
||||
HostsPage.defaultProps = {
|
||||
|
@ -182,6 +193,7 @@ HostsPage.defaultProps = {
|
|||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(
|
||||
|
|
|
@ -176,7 +176,7 @@ export const deleteRule = rule => dispatch => {
|
|||
})
|
||||
.catch(() => {
|
||||
dispatch(
|
||||
publishNotification('error', `${rule.name} could not be deleted`)
|
||||
publishNotification('danger', `${rule.name} could not be deleted`)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ export const updateRuleStatus = (rule, status) => dispatch => {
|
|||
})
|
||||
.catch(() => {
|
||||
dispatch(
|
||||
publishNotification('error', `${rule.name} could not be ${status}`)
|
||||
publishNotification('danger', `${rule.name} could not be ${status}`)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import _ from 'lodash'
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
import {Tab, Tabs, TabPanel, TabPanels, TabList} from 'shared/components/Tabs'
|
||||
import {
|
||||
|
@ -48,8 +52,10 @@ class AlertTabs extends Component {
|
|||
this.setState({configSections: sections})
|
||||
} catch (error) {
|
||||
this.setState({configSections: null})
|
||||
this.props.addFlashMessage({
|
||||
type: 'error',
|
||||
this.props.publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'There was an error getting the Kapacitor config',
|
||||
})
|
||||
}
|
||||
|
@ -81,15 +87,19 @@ class AlertTabs extends Component {
|
|||
propsToSend
|
||||
)
|
||||
this.refreshKapacitorConfig(this.props.kapacitor)
|
||||
this.props.addFlashMessage({
|
||||
this.props.publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
text: `Alert configuration for ${section} successfully saved.`,
|
||||
})
|
||||
return true
|
||||
} catch ({data: {error}}) {
|
||||
const errorMsg = _.join(_.drop(_.split(error, ': '), 2), ': ')
|
||||
this.props.addFlashMessage({
|
||||
type: 'error',
|
||||
this.props.publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: `There was an error saving the alert configuration for ${section}: ${errorMsg}`,
|
||||
})
|
||||
return false
|
||||
|
@ -103,19 +113,25 @@ class AlertTabs extends Component {
|
|||
try {
|
||||
const {data} = await testAlertOutput(this.props.kapacitor, section)
|
||||
if (data.success) {
|
||||
this.props.addFlashMessage({
|
||||
this.props.publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
text: `Successfully triggered an alert to ${section}. If the alert does not reach its destination, please check your configuration settings.`,
|
||||
})
|
||||
} else {
|
||||
this.props.addFlashMessage({
|
||||
type: 'error',
|
||||
this.props.publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: `There was an error sending an alert to ${section}: ${data.message}`,
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
this.props.addFlashMessage({
|
||||
type: 'error',
|
||||
this.props.publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: `There was an error sending an alert to ${section}.`,
|
||||
})
|
||||
}
|
||||
|
@ -329,8 +345,12 @@ AlertTabs.propTypes = {
|
|||
proxy: string.isRequired,
|
||||
}).isRequired,
|
||||
}),
|
||||
addFlashMessage: func.isRequired,
|
||||
publishNotification: func.isRequired,
|
||||
hash: string.isRequired,
|
||||
}
|
||||
|
||||
export default AlertTabs
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(AlertTabs)
|
||||
|
|
|
@ -97,7 +97,6 @@ DataSection.propTypes = {
|
|||
query: shape({
|
||||
id: string.isRequired,
|
||||
}).isRequired,
|
||||
addFlashMessage: func,
|
||||
actions: shape({
|
||||
chooseNamespace: func.isRequired,
|
||||
chooseMeasurement: func.isRequired,
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
import React, {Component, PropTypes} from 'react'
|
||||
|
||||
import AlertTabs from 'src/kapacitor/components/AlertTabs'
|
||||
import FancyScrollbar from 'shared/components/FancyScrollbar'
|
||||
|
||||
class KapacitorForm extends Component {
|
||||
render() {
|
||||
const {
|
||||
onInputChange,
|
||||
onChangeUrl,
|
||||
onReset,
|
||||
kapacitor,
|
||||
onSubmit,
|
||||
exists,
|
||||
} = this.props
|
||||
const {url, name, username, password} = kapacitor
|
||||
return (
|
||||
<div className="page">
|
||||
<div className="page-header">
|
||||
<div className="page-header__container">
|
||||
<div className="page-header__left">
|
||||
<h1 className="page-header__title">{`${exists
|
||||
? 'Configure'
|
||||
: 'Add a New'} Kapacitor Connection`}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-3">
|
||||
<div className="panel">
|
||||
<div className="panel-heading">
|
||||
<h2 className="panel-title">Connection Details</h2>
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<form onSubmit={onSubmit}>
|
||||
<div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="kapaUrl">Kapacitor URL</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="kapaUrl"
|
||||
name="kapaUrl"
|
||||
placeholder={url}
|
||||
value={url}
|
||||
onChange={onChangeUrl}
|
||||
spellCheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="name">Name</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder={name}
|
||||
value={name}
|
||||
onChange={onInputChange}
|
||||
spellCheck="false"
|
||||
maxLength="33"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="username">Username</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="username"
|
||||
name="username"
|
||||
placeholder="username"
|
||||
value={username || ''}
|
||||
onChange={onInputChange}
|
||||
spellCheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="password">Password</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="password"
|
||||
value={password || ''}
|
||||
onChange={onInputChange}
|
||||
spellCheck="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group form-group-submit col-xs-12 text-center">
|
||||
<button
|
||||
className="btn btn-default"
|
||||
type="button"
|
||||
onClick={onReset}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
<button className="btn btn-success" type="submit">
|
||||
{exists ? 'Update' : 'Connect'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-9">
|
||||
{this.renderAlertOutputs()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: move these to another page. they dont belong on this page
|
||||
renderAlertOutputs() {
|
||||
const {exists, kapacitor, source, hash} = this.props
|
||||
|
||||
if (exists) {
|
||||
return <AlertTabs source={source} kapacitor={kapacitor} hash={hash} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="panel">
|
||||
<div className="panel-heading">
|
||||
<h2 className="panel-title">Configure Alert Endpoints</h2>
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<div className="generic-empty-state">
|
||||
<h4 className="no-user-select">
|
||||
Connect to an active Kapacitor instance to configure alerting
|
||||
endpoints
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {func, shape, string, bool} = PropTypes
|
||||
|
||||
KapacitorForm.propTypes = {
|
||||
onSubmit: func.isRequired,
|
||||
onInputChange: func.isRequired,
|
||||
onChangeUrl: func.isRequired,
|
||||
onReset: func.isRequired,
|
||||
kapacitor: shape({
|
||||
url: string.isRequired,
|
||||
name: string.isRequired,
|
||||
username: string,
|
||||
password: string,
|
||||
}).isRequired,
|
||||
source: shape({}).isRequired,
|
||||
exists: bool.isRequired,
|
||||
hash: string.isRequired,
|
||||
}
|
||||
|
||||
export default KapacitorForm
|
|
@ -1,5 +1,7 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import NameSection from 'src/kapacitor/components/NameSection'
|
||||
import ValuesSection from 'src/kapacitor/components/ValuesSection'
|
||||
|
@ -12,6 +14,7 @@ import {createRule, editRule} from 'src/kapacitor/apis'
|
|||
import buildInfluxQLQuery from 'utils/influxql'
|
||||
import {timeRanges} from 'shared/data/timeRanges'
|
||||
import {DEFAULT_RULE_ID} from 'src/kapacitor/constants'
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
class KapacitorRule extends Component {
|
||||
constructor(props) {
|
||||
|
@ -28,7 +31,7 @@ class KapacitorRule extends Component {
|
|||
|
||||
handleCreate = pathname => {
|
||||
const {
|
||||
addFlashMessage,
|
||||
publishNotification,
|
||||
queryConfigs,
|
||||
rule,
|
||||
source,
|
||||
|
@ -44,18 +47,25 @@ class KapacitorRule extends Component {
|
|||
createRule(kapacitor, newRule)
|
||||
.then(() => {
|
||||
router.push(pathname || `/sources/${source.id}/alert-rules`)
|
||||
addFlashMessage({type: 'success', text: 'Rule successfully created'})
|
||||
publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
message: 'Rule successfully created',
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
addFlashMessage({
|
||||
type: 'error',
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'There was a problem creating the rule',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handleEdit = pathname => {
|
||||
const {addFlashMessage, queryConfigs, rule, router, source} = this.props
|
||||
const {publishNotification, queryConfigs, rule, router, source} = this.props
|
||||
const updatedRule = Object.assign({}, rule, {
|
||||
query: queryConfigs[rule.queryID],
|
||||
})
|
||||
|
@ -63,14 +73,18 @@ class KapacitorRule extends Component {
|
|||
editRule(updatedRule)
|
||||
.then(() => {
|
||||
router.push(pathname || `/sources/${source.id}/alert-rules`)
|
||||
addFlashMessage({
|
||||
publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
text: `${rule.name} successfully saved!`,
|
||||
})
|
||||
})
|
||||
.catch(e => {
|
||||
addFlashMessage({
|
||||
type: 'error',
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: `There was a problem saving ${rule.name}: ${e.data.message}`,
|
||||
})
|
||||
})
|
||||
|
@ -234,7 +248,7 @@ KapacitorRule.propTypes = {
|
|||
queryConfigs: shape({}).isRequired,
|
||||
queryConfigActions: shape({}).isRequired,
|
||||
ruleActions: shape({}).isRequired,
|
||||
addFlashMessage: func.isRequired,
|
||||
publishNotification: func.isRequired,
|
||||
ruleID: string.isRequired,
|
||||
handlersFromConfig: arrayOf(shape({})).isRequired,
|
||||
router: shape({
|
||||
|
@ -244,4 +258,8 @@ KapacitorRule.propTypes = {
|
|||
configLink: string.isRequired,
|
||||
}
|
||||
|
||||
export default KapacitorRule
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(KapacitorRule)
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
import React, {Component, PropTypes} from 'react'
|
||||
import {withRouter} from 'react-router'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
import {
|
||||
getKapacitor,
|
||||
createKapacitor,
|
||||
updateKapacitor,
|
||||
pingKapacitor,
|
||||
} from 'shared/apis'
|
||||
import KapacitorForm from '../components/KapacitorForm'
|
||||
|
||||
const defaultName = 'My Kapacitor'
|
||||
const kapacitorPort = '9092'
|
||||
|
||||
class KapacitorPage extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
kapacitor: {
|
||||
url: this._parseKapacitorURL(),
|
||||
name: defaultName,
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
exists: false,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {source, params: {id}} = this.props
|
||||
if (!id) {
|
||||
return
|
||||
}
|
||||
|
||||
getKapacitor(source, id).then(kapacitor => {
|
||||
this.setState({kapacitor})
|
||||
this.checkKapacitorConnection(kapacitor)
|
||||
})
|
||||
}
|
||||
|
||||
checkKapacitorConnection = async kapacitor => {
|
||||
try {
|
||||
await pingKapacitor(kapacitor)
|
||||
this.setState({exists: true})
|
||||
} catch (error) {
|
||||
this.setState({exists: false})
|
||||
this.props.publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'Could not connect to Kapacitor. Check settings.',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleInputChange = e => {
|
||||
const {value, name} = e.target
|
||||
|
||||
this.setState(prevState => {
|
||||
const update = {[name]: value}
|
||||
return {kapacitor: {...prevState.kapacitor, ...update}}
|
||||
})
|
||||
}
|
||||
|
||||
handleChangeUrl = ({value}) => {
|
||||
this.setState({kapacitor: {...this.state.kapacitor, url: value}})
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault()
|
||||
const {
|
||||
publishNotification,
|
||||
source,
|
||||
source: {kapacitors = []},
|
||||
params,
|
||||
router,
|
||||
} = this.props
|
||||
const {kapacitor} = this.state
|
||||
kapacitor.name = kapacitor.name.trim()
|
||||
const isNameTaken = kapacitors.some(k => k.name === kapacitor.name)
|
||||
const isNew = !params.id
|
||||
|
||||
if (isNew && isNameTaken) {
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: `There is already a Kapacitor configuration named "${kapacitor.name}"`,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (params.id) {
|
||||
updateKapacitor(kapacitor)
|
||||
.then(({data}) => {
|
||||
this.setState({kapacitor: data})
|
||||
this.checkKapacitorConnection(data)
|
||||
publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
message: 'Kapacitor Updated!',
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'There was a problem updating the Kapacitor record',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
createKapacitor(source, kapacitor)
|
||||
.then(({data}) => {
|
||||
// need up update kapacitor with info from server to AlertOutputs
|
||||
this.setState({kapacitor: data})
|
||||
this.checkKapacitorConnection(data)
|
||||
router.push(`/sources/${source.id}/kapacitors/${data.id}/edit`)
|
||||
publishNotification({
|
||||
type: 'success',
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
text: 'Kapacitor Created! Configuring endpoints is optional.',
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'There was a problem creating the Kapacitor record',
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleResetToDefaults = e => {
|
||||
e.preventDefault()
|
||||
const defaultState = {
|
||||
url: this._parseKapacitorURL(),
|
||||
name: defaultName,
|
||||
username: '',
|
||||
password: '',
|
||||
}
|
||||
|
||||
this.setState({kapacitor: {...defaultState}})
|
||||
}
|
||||
|
||||
_parseKapacitorURL = () => {
|
||||
const parser = document.createElement('a')
|
||||
parser.href = this.props.source.url
|
||||
|
||||
return `${parser.protocol}//${parser.hostname}:${kapacitorPort}`
|
||||
}
|
||||
|
||||
render() {
|
||||
const {source, location, params} = this.props
|
||||
const hash = (location && location.hash) || (params && params.hash) || ''
|
||||
const {kapacitor, exists} = this.state
|
||||
return (
|
||||
<KapacitorForm
|
||||
onSubmit={this.handleSubmit}
|
||||
onInputChange={this.handleInputChange}
|
||||
onChangeUrl={this.handleChangeUrl}
|
||||
onReset={this.handleResetToDefaults}
|
||||
kapacitor={kapacitor}
|
||||
source={source}
|
||||
exists={exists}
|
||||
hash={hash}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {array, func, shape, string} = PropTypes
|
||||
|
||||
KapacitorPage.propTypes = {
|
||||
publishNotification: func.isRequired,
|
||||
params: shape({
|
||||
id: string,
|
||||
}).isRequired,
|
||||
router: shape({
|
||||
push: func.isRequired,
|
||||
}).isRequired,
|
||||
source: shape({
|
||||
id: string.isRequired,
|
||||
url: string.isRequired,
|
||||
kapacitors: array,
|
||||
}),
|
||||
location: shape({pathname: string, hash: string}).isRequired,
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(withRouter(KapacitorPage))
|
|
@ -10,6 +10,7 @@ import {getActiveKapacitor, getKapacitorConfig} from 'shared/apis/index'
|
|||
import {DEFAULT_RULE_ID} from 'src/kapacitor/constants'
|
||||
import KapacitorRule from 'src/kapacitor/components/KapacitorRule'
|
||||
import parseHandlersFromConfig from 'src/shared/parsing/parseHandlersFromConfig'
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
class KapacitorRulePage extends Component {
|
||||
constructor(props) {
|
||||
|
@ -22,7 +23,7 @@ class KapacitorRulePage extends Component {
|
|||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const {params, source, ruleActions, addFlashMessage} = this.props
|
||||
const {params, source, ruleActions, publishNotification} = this.props
|
||||
|
||||
if (params.ruleID === 'new') {
|
||||
ruleActions.loadDefaultRule()
|
||||
|
@ -32,8 +33,10 @@ class KapacitorRulePage extends Component {
|
|||
|
||||
const kapacitor = await getActiveKapacitor(this.props.source)
|
||||
if (!kapacitor) {
|
||||
return addFlashMessage({
|
||||
type: 'error',
|
||||
return publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: "We couldn't find a configured Kapacitor for this source", // eslint-disable-line quotes
|
||||
})
|
||||
}
|
||||
|
@ -43,8 +46,10 @@ class KapacitorRulePage extends Component {
|
|||
const handlersFromConfig = parseHandlersFromConfig(kapacitorConfig)
|
||||
this.setState({kapacitor, handlersFromConfig})
|
||||
} catch (error) {
|
||||
addFlashMessage({
|
||||
type: 'error',
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
text: 'There was a problem communicating with Kapacitor',
|
||||
})
|
||||
console.error(error)
|
||||
|
@ -60,7 +65,6 @@ class KapacitorRulePage extends Component {
|
|||
router,
|
||||
ruleActions,
|
||||
queryConfigs,
|
||||
addFlashMessage,
|
||||
queryConfigActions,
|
||||
} = this.props
|
||||
const {handlersFromConfig, kapacitor} = this.state
|
||||
|
@ -79,7 +83,6 @@ class KapacitorRulePage extends Component {
|
|||
queryConfigs={queryConfigs}
|
||||
queryConfigActions={queryConfigActions}
|
||||
ruleActions={ruleActions}
|
||||
addFlashMessage={addFlashMessage}
|
||||
handlersFromConfig={handlersFromConfig}
|
||||
ruleID={params.ruleID}
|
||||
router={router}
|
||||
|
@ -99,7 +102,7 @@ KapacitorRulePage.propTypes = {
|
|||
self: string.isRequired,
|
||||
}),
|
||||
}),
|
||||
addFlashMessage: func,
|
||||
publishNotification: func,
|
||||
rules: shape({}).isRequired,
|
||||
queryConfigs: shape({}).isRequired,
|
||||
ruleActions: shape({
|
||||
|
@ -128,6 +131,7 @@ const mapStateToProps = ({rules, kapacitorQueryConfigs: queryConfigs}) => ({
|
|||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
ruleActions: bindActionCreators(kapacitorRuleActionCreators, dispatch),
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
queryConfigActions: bindActionCreators(
|
||||
kapacitorQueryConfigActionCreators,
|
||||
dispatch
|
||||
|
|
|
@ -78,7 +78,6 @@ KapacitorRulesPage.propTypes = {
|
|||
deleteRule: func.isRequired,
|
||||
updateRuleStatus: func.isRequired,
|
||||
}).isRequired,
|
||||
addFlashMessage: func,
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
|
|
|
@ -12,7 +12,6 @@ export const KapacitorTasksPage = React.createClass({
|
|||
kapacitors: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
addFlashMessage: PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
|
|
|
@ -72,7 +72,7 @@ export const removeAndLoadSources = source => async dispatch => {
|
|||
dispatch(loadSources(newSources))
|
||||
} catch (err) {
|
||||
dispatch(
|
||||
publishNotification('error', 'Internal Server Error. Check API Logs')
|
||||
publishNotification('danger', 'Internal Server Error. Check API Logs')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ export const fetchKapacitorsAsync = source => async dispatch => {
|
|||
} catch (err) {
|
||||
dispatch(
|
||||
publishNotification(
|
||||
'error',
|
||||
'danger',
|
||||
`Internal Server Error. Could not retrieve kapacitors for source ${source.id}.`
|
||||
)
|
||||
)
|
||||
|
@ -105,7 +105,7 @@ export const deleteKapacitorAsync = kapacitor => async dispatch => {
|
|||
} catch (err) {
|
||||
dispatch(
|
||||
publishNotification(
|
||||
'error',
|
||||
'danger',
|
||||
'Internal Server Error. Could not delete Kapacitor config.'
|
||||
)
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
setActiveKapacitorAsync,
|
||||
deleteKapacitorAsync,
|
||||
} from 'shared/actions/sources'
|
||||
import {publishNotification as publishNotificationAction} from 'shared/actions/notifications'
|
||||
|
||||
import FancyScrollbar from 'shared/components/FancyScrollbar'
|
||||
import SourceIndicator from 'shared/components/SourceIndicator'
|
||||
|
@ -36,18 +37,22 @@ class ManageSources extends Component {
|
|||
}
|
||||
|
||||
handleDeleteSource = source => () => {
|
||||
const {addFlashMessage} = this.props
|
||||
const {publishNotification} = this.props
|
||||
|
||||
try {
|
||||
this.props.removeAndLoadSources(source)
|
||||
addFlashMessage({
|
||||
publishNotification({
|
||||
type: 'success',
|
||||
text: `Deleted source ${source.name}`,
|
||||
icon: 'checkmark',
|
||||
duration: 5000,
|
||||
message: `Deleted source ${source.name}`,
|
||||
})
|
||||
} catch (e) {
|
||||
addFlashMessage({
|
||||
type: 'error',
|
||||
text: 'Could not remove source from Chronograf',
|
||||
publishNotification({
|
||||
type: 'danger',
|
||||
icon: 'alert-triangle',
|
||||
duration: 10000,
|
||||
message: 'Could not remove source from Chronograf',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +106,7 @@ ManageSources.propTypes = {
|
|||
}),
|
||||
}),
|
||||
sources: array,
|
||||
addFlashMessage: func,
|
||||
publishNotification: func.isRequired,
|
||||
removeAndLoadSources: func.isRequired,
|
||||
fetchKapacitors: func.isRequired,
|
||||
setActiveKapacitor: func.isRequired,
|
||||
|
@ -117,6 +122,7 @@ const mapDispatchToProps = dispatch => ({
|
|||
fetchKapacitors: bindActionCreators(fetchKapacitorsAsync, dispatch),
|
||||
setActiveKapacitor: bindActionCreators(setActiveKapacitorAsync, dispatch),
|
||||
deleteKapacitor: bindActionCreators(deleteKapacitorAsync, dispatch),
|
||||
publishNotification: bindActionCreators(publishNotificationAction, dispatch),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ManageSources)
|
||||
|
|
Loading…
Reference in New Issue