problems ack dialog: submit on enter and show error for empty message
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
"babel-preset-env": "^1.7.0",
|
"babel-preset-env": "^1.7.0",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
"clean-webpack-plugin": "^0.1.19",
|
"clean-webpack-plugin": "^0.1.19",
|
||||||
"codecov": "^3.1.0",
|
"codecov": "^3.1.0",
|
||||||
"copy-webpack-plugin": "^4.5.4",
|
"copy-webpack-plugin": "^4.5.4",
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
const KEYBOARD_ENTER_KEY = 13;
|
||||||
|
const KEYBOARD_ESCAPE_KEY = 27;
|
||||||
|
|
||||||
interface ModalProps {
|
interface ModalProps {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
@@ -10,6 +14,8 @@ interface ModalProps {
|
|||||||
|
|
||||||
interface ModalState {
|
interface ModalState {
|
||||||
value: string;
|
value: string;
|
||||||
|
error: boolean;
|
||||||
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AckProblemData {
|
export interface AckProblemData {
|
||||||
@@ -23,23 +29,43 @@ export class Modal extends PureComponent<ModalProps, ModalState> {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { value: '' };
|
this.state = {
|
||||||
|
value: '',
|
||||||
|
error: false,
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
|
||||||
this.modalContainer = document.body;
|
this.modalContainer = document.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({ value: event.target.value });
|
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 = () => {
|
dismiss = () => {
|
||||||
console.log('dismiss');
|
this.setState({ value: '', error: false, message: '' });
|
||||||
this.setState({ value: '' });
|
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
submit = () => {
|
submit = () => {
|
||||||
console.log('submit', this.state.value);
|
if (!this.state.value) {
|
||||||
|
return this.setState({
|
||||||
|
error: true,
|
||||||
|
message: 'Enter message text'
|
||||||
|
});
|
||||||
|
}
|
||||||
this.props.onSubmit({
|
this.props.onSubmit({
|
||||||
message: this.state.value
|
message: this.state.value
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@@ -52,8 +78,10 @@ export class Modal extends PureComponent<ModalProps, ModalState> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const inputClass = classNames('gf-form-input', { 'zbx-ack-error': this.state.error });
|
||||||
|
|
||||||
const modalNode = (
|
const modalNode = (
|
||||||
<div className="modal modal--narrow" key="modal">
|
<div className="modal modal--narrow zbx-ack-modal" key="modal">
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h2 className="modal-header-title">
|
<h2 className="modal-header-title">
|
||||||
@@ -66,10 +94,9 @@ export class Modal extends PureComponent<ModalProps, ModalState> {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
{/* Message */}
|
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
<label className="gf-form-hint">
|
<label className="gf-form-hint">
|
||||||
<input className="gf-form-input"
|
<input className={inputClass}
|
||||||
type="text"
|
type="text"
|
||||||
name="message"
|
name="message"
|
||||||
placeholder="Message"
|
placeholder="Message"
|
||||||
@@ -77,10 +104,17 @@ export class Modal extends PureComponent<ModalProps, ModalState> {
|
|||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
onChange={this.handleChange}>
|
onChange={this.handleChange}
|
||||||
|
onKeyUp={this.handleKeyUp}>
|
||||||
</input>
|
</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>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="gf-form">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="gf-form-button-row text-center">
|
<div className="gf-form-button-row text-center">
|
||||||
<button className="btn btn-success" onClick={this.submit}>Acknowledge</button>
|
<button className="btn btn-success" onClick={this.submit}>Acknowledge</button>
|
||||||
@@ -93,7 +127,7 @@ export class Modal extends PureComponent<ModalProps, ModalState> {
|
|||||||
|
|
||||||
const modalNodeWithBackdrop = [
|
const modalNodeWithBackdrop = [
|
||||||
modalNode,
|
modalNode,
|
||||||
<div className="modal-backdrop in" key="modal-backdrop"></div>
|
<div className="modal-backdrop in" key="modal-backdrop" onClick={this.handleBackdropClick}></div>
|
||||||
];
|
];
|
||||||
|
|
||||||
const modal = this.props.withBackdrop ? modalNodeWithBackdrop : modalNode;
|
const modal = this.props.withBackdrop ? modalNodeWithBackdrop : modalNode;
|
||||||
|
|||||||
@@ -510,6 +510,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.zbx-ack-modal {
|
||||||
|
.gf-form-input.zbx-ack-error {
|
||||||
|
border-color: $btn-danger-bg;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 5px $btn-danger-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gf-form .gf-form-hint {
|
||||||
|
.gf-form-hint-text {
|
||||||
|
display: inherit;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
&.ack-error-message {
|
||||||
|
float: left;
|
||||||
|
color: $error-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes slide-down {
|
@keyframes slide-down {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@@ -1821,7 +1821,7 @@ class-utils@^0.3.5:
|
|||||||
isobject "^3.0.0"
|
isobject "^3.0.0"
|
||||||
static-extend "^0.1.1"
|
static-extend "^0.1.1"
|
||||||
|
|
||||||
classnames@^2.2.5:
|
classnames@^2.2.5, classnames@^2.2.6:
|
||||||
version "2.2.6"
|
version "2.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||||
|
|||||||
Reference in New Issue
Block a user