Files
grafana-zabbix/src/panel-triggers/components/Modal.tsx

137 lines
3.8 KiB
TypeScript

import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
const KEYBOARD_ENTER_KEY = 13;
const KEYBOARD_ESCAPE_KEY = 27;
interface ModalProps {
isOpen?: boolean;
withBackdrop?: boolean;
onSubmit: (data?: AckProblemData) => Promise<any> | any;
onClose?: () => void;
}
interface ModalState {
value: string;
error: boolean;
message: string;
}
export interface AckProblemData {
message: string;
closeProblem?: boolean;
action?: number;
}
export class Modal extends PureComponent<ModalProps, ModalState> {
modalContainer: HTMLElement;
constructor(props) {
super(props);
this.state = {
value: '',
error: false,
message: '',
};
this.modalContainer = document.body;
}
handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ value: event.target.value, error: false });
}
handleKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {
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();
}
dismiss = () => {
this.setState({ value: '', error: false, message: '' });
this.props.onClose();
}
submit = () => {
if (!this.state.value) {
return this.setState({
error: true,
message: 'Enter message text'
});
}
this.props.onSubmit({
message: this.state.value
}).then(() => {
this.dismiss();
});
}
render() {
if (!this.props.isOpen || !this.modalContainer) {
return null;
}
const inputClass = classNames('gf-form-input', { 'zbx-ack-error': this.state.error });
const modalNode = (
<div className="modal modal--narrow zbx-ack-modal" key="modal">
<div className="modal-body">
<div className="modal-header">
<h2 className="modal-header-title">
<i className="fa fa-reply-all"></i>
<span className="p-l-1">Acknowledge Problem</span>
</h2>
<a className="modal-header-close" onClick={this.dismiss}>
<i className="fa fa-remove"></i>
</a>
</div>
<div className="modal-content">
<div className="gf-form">
<label className="gf-form-hint">
<input className={inputClass}
type="text"
name="message"
placeholder="Message"
maxLength={64}
autoComplete="off"
autoFocus={true}
value={this.state.value}
onChange={this.handleChange}
onKeyUp={this.handleKeyUp}>
</input>
<small className="gf-form-hint-text muted">Press Enter to submit</small>
{this.state.error &&
<small className="gf-form-hint-text muted ack-error-message">{this.state.message}</small>
}
</label>
</div>
<div className="gf-form">
</div>
<div className="gf-form-button-row text-center">
<button className="btn btn-success" onClick={this.submit}>Acknowledge</button>
<button className="btn btn-inverse" onClick={this.dismiss}>Cancel</button>
</div>
</div>
</div>
</div>
);
const modalNodeWithBackdrop = [
modalNode,
<div className="modal-backdrop in" key="modal-backdrop" onClick={this.handleBackdropClick}></div>
];
const modal = this.props.withBackdrop ? modalNodeWithBackdrop : modalNode;
return ReactDOM.createPortal(modal, this.modalContainer);
}
}