Add delete button and funcitonality for SlackConfigs
parent
5330d2c5a7
commit
dbd32a9952
|
@ -13,6 +13,7 @@ import {
|
|||
getKapacitorConfig,
|
||||
updateKapacitorConfigSection,
|
||||
addKapacitorConfigInSection,
|
||||
deleteKapacitorConfigInSection,
|
||||
testAlertOutput,
|
||||
getAllServices,
|
||||
} from 'src/shared/apis'
|
||||
|
@ -36,6 +37,8 @@ import {
|
|||
notifyRefreshKapacitorFailed,
|
||||
notifyAlertEndpointSaved,
|
||||
notifyAlertEndpointSaveFailed,
|
||||
notifyAlertEndpointDeleteFailed,
|
||||
notifyAlertEndpointDeleted,
|
||||
notifyTestAlertSent,
|
||||
notifyTestAlertFailed,
|
||||
notifyCouldNotRetrieveKapacitorServices,
|
||||
|
@ -43,7 +46,7 @@ import {
|
|||
import DeprecationWarning from 'src/admin/components/DeprecationWarning'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
import {Source, Kapacitor} from 'src/types'
|
||||
import {Source, Kapacitor, NotificationFunc} from 'src/types'
|
||||
import SlackConfigs from 'src/kapacitor/components/config/SlackConfigs'
|
||||
|
||||
interface Service {
|
||||
|
@ -95,6 +98,7 @@ interface Config {
|
|||
type: string
|
||||
enabled: boolean
|
||||
renderComponent: () => JSX.Element
|
||||
notify?: (message: Notification | NotificationFunc) => void
|
||||
}
|
||||
|
||||
interface SupportedConfig {
|
||||
|
@ -171,11 +175,11 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
return null
|
||||
}
|
||||
|
||||
const pagerDutyV1Enabled: boolean = this.getEnabled(
|
||||
const pagerDutyV1Enabled: boolean = this.getConfigEnabled(
|
||||
configSections,
|
||||
'pagerduty'
|
||||
)
|
||||
const opsGenieV1Enabled: boolean = this.getEnabled(
|
||||
const opsGenieV1Enabled: boolean = this.getConfigEnabled(
|
||||
configSections,
|
||||
'opsgenie'
|
||||
)
|
||||
|
@ -205,31 +209,31 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
const supportedConfigs: SupportedConfig = {
|
||||
alerta: {
|
||||
type: 'Alerta',
|
||||
enabled: this.getEnabled(configSections, 'alerta'),
|
||||
enabled: this.getConfigEnabled(configSections, 'alerta'),
|
||||
renderComponent: () => (
|
||||
<AlertaConfig
|
||||
onSave={this.handleSaveConfig('alerta')}
|
||||
config={this.getSectionElement(configSections, 'alerta')}
|
||||
onTest={this.handleTestConfig('alerta')}
|
||||
enabled={this.getEnabled(configSections, 'alerta')}
|
||||
enabled={this.getConfigEnabled(configSections, 'alerta')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
hipchat: {
|
||||
type: 'HipChat',
|
||||
enabled: this.getEnabled(configSections, 'hipchat'),
|
||||
enabled: this.getConfigEnabled(configSections, 'hipchat'),
|
||||
renderComponent: () => (
|
||||
<HipChatConfig
|
||||
onSave={this.handleSaveConfig('hipchat')}
|
||||
config={this.getSectionElement(configSections, 'hipchat')}
|
||||
onTest={this.handleTestConfig('hipchat')}
|
||||
enabled={this.getEnabled(configSections, 'hipchat')}
|
||||
enabled={this.getConfigEnabled(configSections, 'hipchat')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
kafka: {
|
||||
type: 'Kafka',
|
||||
enabled: this.getEnabled(configSections, 'kafka'),
|
||||
enabled: this.getConfigEnabled(configSections, 'kafka'),
|
||||
renderComponent: () => (
|
||||
<KafkaConfig
|
||||
onSave={this.handleSaveConfig('kafka')}
|
||||
|
@ -237,145 +241,146 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
onTest={this.handleTestConfig('kafka', {
|
||||
cluster: this.getProperty(configSections, 'kafka', 'id'),
|
||||
})}
|
||||
enabled={this.getEnabled(configSections, 'kafka')}
|
||||
enabled={this.getConfigEnabled(configSections, 'kafka')}
|
||||
notify={this.props.notify}
|
||||
/>
|
||||
),
|
||||
},
|
||||
opsgenie: {
|
||||
type: 'OpsGenie',
|
||||
enabled: this.getEnabled(configSections, 'opsgenie'),
|
||||
enabled: this.getConfigEnabled(configSections, 'opsgenie'),
|
||||
renderComponent: () => (
|
||||
<OpsGenieConfig
|
||||
onSave={this.handleSaveConfig('opsgenie')}
|
||||
config={this.getSectionElement(configSections, 'opsgenie')}
|
||||
onTest={this.handleTestConfig('opsgenie')}
|
||||
enabled={this.getEnabled(configSections, 'opsgenie')}
|
||||
enabled={this.getConfigEnabled(configSections, 'opsgenie')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
opsgenie2: {
|
||||
type: 'OpsGenie2',
|
||||
enabled: this.getEnabled(configSections, 'opsgenie2'),
|
||||
enabled: this.getConfigEnabled(configSections, 'opsgenie2'),
|
||||
renderComponent: () => (
|
||||
<OpsGenieConfig
|
||||
onSave={this.handleSaveConfig('opsgenie2')}
|
||||
config={this.getSectionElement(configSections, 'opsgenie2')}
|
||||
onTest={this.handleTestConfig('opsgenie2')}
|
||||
enabled={this.getEnabled(configSections, 'opsgenie2')}
|
||||
enabled={this.getConfigEnabled(configSections, 'opsgenie2')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
pagerduty: {
|
||||
type: 'PagerDuty',
|
||||
enabled: this.getEnabled(configSections, 'pagerduty'),
|
||||
enabled: this.getConfigEnabled(configSections, 'pagerduty'),
|
||||
renderComponent: () => (
|
||||
<PagerDutyConfig
|
||||
onSave={this.handleSaveConfig('pagerduty')}
|
||||
config={this.getSectionElement(configSections, 'pagerduty')}
|
||||
onTest={this.handleTestConfig('pagerduty')}
|
||||
enabled={this.getEnabled(configSections, 'pagerduty')}
|
||||
enabled={this.getConfigEnabled(configSections, 'pagerduty')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
pagerduty2: {
|
||||
type: 'PagerDuty2',
|
||||
enabled: this.getEnabled(configSections, 'pagerduty2'),
|
||||
enabled: this.getConfigEnabled(configSections, 'pagerduty2'),
|
||||
renderComponent: () => (
|
||||
<PagerDuty2Config
|
||||
onSave={this.handleSaveConfig('pagerduty2')}
|
||||
config={this.getSectionElement(configSections, 'pagerduty2')}
|
||||
onTest={this.handleTestConfig('pagerduty2')}
|
||||
enabled={this.getEnabled(configSections, 'pagerduty2')}
|
||||
enabled={this.getConfigEnabled(configSections, 'pagerduty2')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
pushover: {
|
||||
type: 'Pushover',
|
||||
enabled: this.getEnabled(configSections, 'pushover'),
|
||||
enabled: this.getConfigEnabled(configSections, 'pushover'),
|
||||
renderComponent: () => (
|
||||
<PushoverConfig
|
||||
onSave={this.handleSaveConfig('pushover')}
|
||||
config={this.getSectionElement(configSections, 'pushover')}
|
||||
onTest={this.handleTestConfig('pushover')}
|
||||
enabled={this.getEnabled(configSections, 'pushover')}
|
||||
enabled={this.getConfigEnabled(configSections, 'pushover')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
sensu: {
|
||||
type: 'Sensu',
|
||||
enabled: this.getEnabled(configSections, 'sensu'),
|
||||
enabled: this.getConfigEnabled(configSections, 'sensu'),
|
||||
renderComponent: () => (
|
||||
<SensuConfig
|
||||
onSave={this.handleSaveConfig('sensu')}
|
||||
config={this.getSectionElement(configSections, 'sensu')}
|
||||
onTest={this.handleTestConfig('sensu')}
|
||||
enabled={this.getEnabled(configSections, 'sensu')}
|
||||
enabled={this.getConfigEnabled(configSections, 'sensu')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
slack: {
|
||||
type: 'Slack',
|
||||
enabled: this.getEnabled(configSections, 'slack'),
|
||||
enabled: this.getConfigEnabled(configSections, 'slack'),
|
||||
renderComponent: () => (
|
||||
<SlackConfigs
|
||||
slackConfigs={this.getSectionElements(configSections, 'slack')}
|
||||
configs={this.getSectionElements(configSections, 'slack')}
|
||||
onSave={this.handleSaveConfig('slack')}
|
||||
config={this.getSectionElement(configSections, 'slack')}
|
||||
onTest={this.handleTestConfig('slack')}
|
||||
enabled={this.getEnabled(configSections, 'slack')}
|
||||
onDelete={this.handleDeleteConfig('slack')}
|
||||
onEnabled={this.getSpecificConfigEnabled(configSections, 'slack')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
smtp: {
|
||||
type: 'SMTP',
|
||||
enabled: this.getEnabled(configSections, 'smtp'),
|
||||
enabled: this.getConfigEnabled(configSections, 'smtp'),
|
||||
renderComponent: () => (
|
||||
<SMTPConfig
|
||||
onSave={this.handleSaveConfig('smtp')}
|
||||
config={this.getSectionElement(configSections, 'smtp')}
|
||||
onTest={this.handleTestConfig('smtp')}
|
||||
enabled={this.getEnabled(configSections, 'smtp')}
|
||||
enabled={this.getConfigEnabled(configSections, 'smtp')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
talk: {
|
||||
type: 'Talk',
|
||||
enabled: this.getEnabled(configSections, 'talk'),
|
||||
enabled: this.getConfigEnabled(configSections, 'talk'),
|
||||
renderComponent: () => (
|
||||
<TalkConfig
|
||||
onSave={this.handleSaveConfig('talk')}
|
||||
config={this.getSectionElement(configSections, 'talk')}
|
||||
onTest={this.handleTestConfig('talk')}
|
||||
enabled={this.getEnabled(configSections, 'talk')}
|
||||
enabled={this.getConfigEnabled(configSections, 'talk')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
telegram: {
|
||||
type: 'Telegram',
|
||||
enabled: this.getEnabled(configSections, 'telegram'),
|
||||
enabled: this.getConfigEnabled(configSections, 'telegram'),
|
||||
renderComponent: () => (
|
||||
<TelegramConfig
|
||||
onSave={this.handleSaveConfig('telegram')}
|
||||
config={this.getSectionElement(configSections, 'telegram')}
|
||||
onTest={this.handleTestConfig('telegram')}
|
||||
enabled={this.getEnabled(configSections, 'telegram')}
|
||||
enabled={this.getConfigEnabled(configSections, 'telegram')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
victorops: {
|
||||
type: 'VictorOps',
|
||||
enabled: this.getEnabled(configSections, 'victorops'),
|
||||
enabled: this.getConfigEnabled(configSections, 'victorops'),
|
||||
renderComponent: () => (
|
||||
<VictorOpsConfig
|
||||
onSave={this.handleSaveConfig('victorops')}
|
||||
config={this.getSectionElement(configSections, 'victorops')}
|
||||
onTest={this.handleTestConfig('victorops')}
|
||||
enabled={this.getEnabled(configSections, 'victorops')}
|
||||
enabled={this.getConfigEnabled(configSections, 'victorops')}
|
||||
/>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="panel">
|
||||
<div className="panel-heading">
|
||||
|
@ -445,10 +450,9 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
|
||||
private getSectionElement = (
|
||||
sections: Sections,
|
||||
section: string,
|
||||
elementIndex: number = 0
|
||||
section: string
|
||||
): Element => {
|
||||
return _.get(sections, [section, 'elements', elementIndex], null)
|
||||
return _.get(sections, [section, 'elements', '0'], null)
|
||||
}
|
||||
|
||||
private getSectionElements = (
|
||||
|
@ -458,7 +462,7 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
return _.get(sections, [section, 'elements'], null)
|
||||
}
|
||||
|
||||
private getEnabled = (sections: Sections, section: string): boolean => {
|
||||
private getConfigEnabled = (sections: Sections, section: string): boolean => {
|
||||
return _.get(
|
||||
sections,
|
||||
[section, 'elements', '0', 'options', 'enabled'],
|
||||
|
@ -478,6 +482,20 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
)
|
||||
}
|
||||
|
||||
private getSpecificConfigEnabled = (sections: Sections, section: string) => (
|
||||
specificConfig: string
|
||||
): boolean => {
|
||||
const elements: Element[] = this.getSectionElements(sections, section)
|
||||
const elementIndex = elements.findIndex(
|
||||
element => _.get(element, ['options', 'workspace']) === specificConfig
|
||||
)
|
||||
return _.get(
|
||||
sections,
|
||||
[section, 'elements', elementIndex.toString(), 'options', 'enabled'],
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
private handleSaveConfig = (section: string) => async (
|
||||
properties,
|
||||
isNewConfigInSection?: boolean,
|
||||
|
@ -533,6 +551,27 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
private handleDeleteConfig = (section: string) => async (
|
||||
specificConfig: string
|
||||
): Promise<void> => {
|
||||
try {
|
||||
await deleteKapacitorConfigInSection(
|
||||
this.props.kapacitor,
|
||||
section,
|
||||
specificConfig
|
||||
)
|
||||
|
||||
await this.refreshKapacitorConfig(this.props.kapacitor)
|
||||
|
||||
this.props.notify(notifyAlertEndpointDeleted(section, specificConfig))
|
||||
} catch (error) {
|
||||
const errorMsg = _.join(_.drop(_.split(error, ': '), 2), ': ')
|
||||
this.props.notify(
|
||||
notifyAlertEndpointDeleteFailed(section, specificConfig, errorMsg)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private sanitizeProperties = (section: string, properties: Props): Props => {
|
||||
const cleanProps = {enabled: true, ...properties}
|
||||
const {redacted} = this.getSectionElement(
|
||||
|
|
|
@ -27,6 +27,7 @@ interface Props {
|
|||
specificConfig: string
|
||||
) => void
|
||||
onTest: (event: React.MouseEvent<HTMLButtonElement>) => void
|
||||
onDelete: (specificConfig: string) => void
|
||||
enabled: boolean
|
||||
isNewConfig: boolean
|
||||
}
|
||||
|
@ -60,6 +61,8 @@ class SlackConfig extends PureComponent<Props, State> {
|
|||
const {testEnabled, enabled} = this.state
|
||||
const workspaceID = workspace || 'default'
|
||||
|
||||
const isNickNameEnabled = isNewConfig && !testEnabled
|
||||
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div className="form-group col-xs-12">
|
||||
|
@ -70,11 +73,11 @@ class SlackConfig extends PureComponent<Props, State> {
|
|||
className="form-control"
|
||||
id={`${workspaceID}-nickname`}
|
||||
type="text"
|
||||
placeholder="Optional unless multiple Slack configurations exist"
|
||||
placeholder="Only for additional Configurations"
|
||||
ref={r => (this.workspace = r)}
|
||||
defaultValue={workspace || ''}
|
||||
onChange={this.disableTest}
|
||||
disabled={!isNewConfig}
|
||||
disabled={!isNickNameEnabled}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12">
|
||||
|
@ -140,6 +143,10 @@ class SlackConfig extends PureComponent<Props, State> {
|
|||
<span className="icon pulse-c" />
|
||||
Send Test Alert
|
||||
</button>
|
||||
<button className="btn btn-danger" onClick={this.handleDelete}>
|
||||
<span className="icon trash" />
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
|
@ -173,6 +180,11 @@ class SlackConfig extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
private handleDelete = async e => {
|
||||
e.preventDefault()
|
||||
await this.props.onDelete(this.workspace.value)
|
||||
}
|
||||
|
||||
private disableTest = () => {
|
||||
this.setState({testEnabled: false})
|
||||
}
|
||||
|
|
|
@ -19,19 +19,19 @@ interface Config {
|
|||
}
|
||||
|
||||
interface Props {
|
||||
slackConfigs: any[]
|
||||
config: Config
|
||||
configs: Config[]
|
||||
onSave: (
|
||||
properties: Properties,
|
||||
isNewConfigInSection: boolean,
|
||||
specificConfig: string
|
||||
) => void
|
||||
onDelete: (specificConfig: string) => void
|
||||
onTest: (event: React.MouseEvent<HTMLButtonElement>) => void
|
||||
enabled: boolean
|
||||
onEnabled: (specificConfig: string) => boolean
|
||||
}
|
||||
|
||||
interface State {
|
||||
slackConfigs: any[]
|
||||
configs: any[]
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -39,30 +39,32 @@ class SlackConfigs extends PureComponent<Props, State> {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
slackConfigs: this.props.slackConfigs,
|
||||
configs: this.props.configs,
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps) {
|
||||
this.setState({configs: nextProps.configs})
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {slackConfigs} = this.state
|
||||
const {onSave, onTest, enabled} = this.props
|
||||
const configNums = slackConfigs.length
|
||||
const {configs} = this.state
|
||||
const {onSave, onTest, onDelete, onEnabled} = this.props
|
||||
|
||||
return (
|
||||
<div>
|
||||
{slackConfigs.map(config => {
|
||||
const key = _.get(config, ['options', 'workspace'], 'default')
|
||||
const configEnabled = _.get(config, ['options', 'enabled'], false)
|
||||
const isFirstConfigNew = configNums === 1 && !configEnabled
|
||||
const isNewConfig =
|
||||
isFirstConfigNew || _.get(config, 'isNewConfig', false)
|
||||
{configs.map(config => {
|
||||
const workspace = _.get(config, ['options', 'workspace'], 'new')
|
||||
const isNewConfig = _.get(config, 'isNewConfig', false)
|
||||
const enabled = onEnabled(workspace)
|
||||
|
||||
return (
|
||||
<SlackConfig
|
||||
key={key}
|
||||
key={workspace}
|
||||
onSave={onSave}
|
||||
config={config}
|
||||
onTest={onTest}
|
||||
onDelete={onDelete}
|
||||
enabled={enabled}
|
||||
isNewConfig={isNewConfig}
|
||||
/>
|
||||
|
@ -75,12 +77,12 @@ class SlackConfigs extends PureComponent<Props, State> {
|
|||
)
|
||||
}
|
||||
|
||||
private get slackConfigs() {
|
||||
return this.state.slackConfigs
|
||||
private get configs() {
|
||||
return this.state.configs
|
||||
}
|
||||
|
||||
private addConfig = () => {
|
||||
const configs = this.slackConfigs
|
||||
const configs = this.configs
|
||||
const newConfig = {
|
||||
options: {
|
||||
url: false,
|
||||
|
@ -88,7 +90,7 @@ class SlackConfigs extends PureComponent<Props, State> {
|
|||
},
|
||||
isNewConfig: true,
|
||||
}
|
||||
this.setState({slackConfigs: [...configs, newConfig]})
|
||||
this.setState({configs: [...configs, newConfig]})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,10 +155,6 @@ export const getKapacitorConfigSection = (kapacitor, section) => {
|
|||
return kapacitorProxy(kapacitor, 'GET', `/kapacitor/v1/config/${section}`, '')
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
export function updateKapacitorConfigSection(kapacitor, section, properties) {
|
||||
const params = {
|
||||
=======
|
||||
export function updateKapacitorConfigSection(
|
||||
kapacitor,
|
||||
section,
|
||||
|
@ -168,8 +164,7 @@ export function updateKapacitorConfigSection(
|
|||
const config = specificConfig || ''
|
||||
const path = `/kapacitor/v1/config/${section}/${config}`
|
||||
|
||||
return AJAX({
|
||||
>>>>>>> Change updateKapacitorConfigSection function so that if a specific config is passed, it updates that specific config and not just the default
|
||||
const params = {
|
||||
method: 'POST',
|
||||
url: kapacitor.links.proxy,
|
||||
params: {
|
||||
|
@ -202,6 +197,28 @@ export function addKapacitorConfigInSection(kapacitor, section, properties) {
|
|||
})
|
||||
}
|
||||
|
||||
export function deleteKapacitorConfigInSection(
|
||||
kapacitor,
|
||||
section,
|
||||
specificConfig
|
||||
) {
|
||||
const path = `/kapacitor/v1/config/${section}`
|
||||
|
||||
return AJAX({
|
||||
method: 'POST',
|
||||
url: kapacitor.links.proxy,
|
||||
params: {
|
||||
path,
|
||||
},
|
||||
data: {
|
||||
remove: [specificConfig],
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const testAlertOutput = async (kapacitor, outputName, options) => {
|
||||
try {
|
||||
const {
|
||||
|
|
|
@ -516,6 +516,20 @@ export const notifyAlertEndpointSaveFailed = (endpoint, errorMessage) => ({
|
|||
message: `There was an error saving the alert configuration for ${endpoint}: ${errorMessage}`,
|
||||
})
|
||||
|
||||
export const notifyAlertEndpointDeleteFailed = (
|
||||
endpoint,
|
||||
config,
|
||||
errorMessage
|
||||
) => ({
|
||||
...defaultErrorNotification,
|
||||
message: `There was an error deleting the alert configuration for ${endpoint}/${config}: ${errorMessage}`,
|
||||
})
|
||||
|
||||
export const notifyAlertEndpointDeleted = (endpoint, config) => ({
|
||||
...defaultSuccessNotification,
|
||||
message: `Alert configuration for ${endpoint}/${config} deleted successfully.`,
|
||||
})
|
||||
|
||||
export const notifyTestAlertSent = endpoint => ({
|
||||
...defaultSuccessNotification,
|
||||
duration: TEN_SECONDS,
|
||||
|
|
Loading…
Reference in New Issue