import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; import classNames from 'classnames'; import { ZBX_ACK_ACTION_ADD_MESSAGE, ZBX_ACK_ACTION_ACK, ZBX_ACK_ACTION_CHANGE_SEVERITY, ZBX_ACK_ACTION_CLOSE } from '../../datasource-zabbix/constants'; import { Button, Input, VerticalGroup, Spinner } from '@grafana/ui'; import { FAIcon } from './FAIcon'; import * as grafanaUi from '@grafana/ui'; const Checkbox: any = grafanaUi.Forms?.Checkbox || (grafanaUi as any).Checkbox; const RadioButtonGroup: any = grafanaUi.Forms?.RadioButtonGroup || (grafanaUi as any).RadioButtonGroup; const KEYBOARD_ENTER_KEY = 13; const KEYBOARD_ESCAPE_KEY = 27; interface Props { canAck?: boolean; canClose?: boolean; isOpen?: boolean; withBackdrop?: boolean; onSubmit: (data?: AckProblemData) => Promise | any; onClose?: () => void; } interface State { value: string; error: boolean; errorMessage: string; ackError: string; acknowledge: boolean; closeProblem: boolean; changeSeverity: boolean; selectedSeverity: number; loading: boolean; } export interface AckProblemData { message: string; closeProblem?: boolean; action?: number; severity?: number; } const severityOptions = [ {value: 0, label: 'Not classified'}, {value: 1, label: 'Information'}, {value: 2, label: 'Warning'}, {value: 3, label: 'Average'}, {value: 4, label: 'High'}, {value: 5, label: 'Disaster'} ]; export class AckModal extends PureComponent { modalContainer: HTMLElement; static defaultProps: Partial = { withBackdrop: true, }; constructor(props) { super(props); this.state = { value: '', error: false, errorMessage: '', ackError: '', acknowledge: false, closeProblem: false, changeSeverity: false, selectedSeverity: 0, loading: false, }; this.modalContainer = document.body; } handleChange = (event: React.ChangeEvent) => { this.setState({ value: event.target.value, error: false }); } handleKeyUp = (event: React.KeyboardEvent) => { if (event.which === KEYBOARD_ENTER_KEY || event.key === 'Enter') { this.submit(); } else if (event.which === KEYBOARD_ESCAPE_KEY || event.key === 'Escape') { this.dismiss(); } } handleBackdropClick = () => { this.dismiss(); } onAcknowledgeToggle = () => { this.setState({ acknowledge: !this.state.acknowledge, error: false }); } onChangeSeverityToggle = () => { this.setState({ changeSeverity: !this.state.changeSeverity, error: false }); } onCloseProblemToggle = () => { this.setState({ closeProblem: !this.state.closeProblem, error: false }); } onChangeSelectedSeverity = v => { this.setState({ selectedSeverity: v }); }; dismiss = () => { this.setState({ value: '', error: false, errorMessage: '', ackError: '', loading: false }); this.props.onClose(); } submit = () => { const { acknowledge, changeSeverity, closeProblem } = this.state; const actionSelected = acknowledge || changeSeverity || closeProblem; if (!this.state.value && !actionSelected) { return this.setState({ error: true, errorMessage: 'Enter message text or select an action' }); } this.setState({ ackError: '', loading: true }); const ackData: AckProblemData = { message: this.state.value, }; let action = ZBX_ACK_ACTION_ADD_MESSAGE; if (this.state.acknowledge) { action += ZBX_ACK_ACTION_ACK; } if (this.state.changeSeverity) { action += ZBX_ACK_ACTION_CHANGE_SEVERITY; ackData.severity = this.state.selectedSeverity; } if (this.state.closeProblem) { action += ZBX_ACK_ACTION_CLOSE; } ackData.action = action; this.props.onSubmit(ackData).then((response) => { this.dismiss(); }).catch(err => { this.setState({ ackError: err.message || err.data, loading: false, }); }); } render() { const { canClose, canAck } = this.props; if (!this.props.isOpen || !this.modalContainer) { return null; } const inputClass = classNames({ 'zbx-ack-error': this.state.error }); const modalNode = (

{this.state.loading ? : } Acknowledge Problem

{this.state.changeSeverity && } {canClose && }
{this.state.ackError &&
{this.state.ackError}
}
); const modalNodeWithBackdrop = [ modalNode,
]; const modal = this.props.withBackdrop ? modalNodeWithBackdrop : modalNode; return ReactDOM.createPortal(modal, this.modalContainer); } }