UI: pretty error messages

Add Toast component for displaying error messages in a more prominent way
master
Andrew P Maney 5 years ago committed by GitHub
parent 0ce83defcc
commit 7a42ff04d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -24,6 +24,7 @@ import DateTimePicker from '../widgets/DateTimePicker';
import ConfirmationDialog from '../widgets/ConfirmationDialog'; import ConfirmationDialog from '../widgets/ConfirmationDialog';
import TimezonePicker from '../widgets/TimezonePicker'; import TimezonePicker from '../widgets/TimezonePicker';
import Toast from '../widgets/Toast';
import { Location } from 'history'; import { Location } from 'history';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
@ -138,6 +139,7 @@ class EventEdit extends React.PureComponent<PropsType> {
this.onDeleteRequest = this.onDeleteRequest.bind(this); this.onDeleteRequest = this.onDeleteRequest.bind(this);
this.toggleRecurring = this.toggleRecurring.bind(this); this.toggleRecurring = this.toggleRecurring.bind(this);
this.handleRRuleChange = this.handleRRuleChange.bind(this); this.handleRRuleChange = this.handleRRuleChange.bind(this);
this.handleCloseToast = this.handleCloseToast.bind(this);
} }
public UNSAFE_componentWillReceiveProps(nextProps: any) { public UNSAFE_componentWillReceiveProps(nextProps: any) {
@ -180,6 +182,15 @@ class EventEdit extends React.PureComponent<PropsType> {
public handleRRuleChange(rrule: RRuleOptions): void { public handleRRuleChange(rrule: RRuleOptions): void {
this.setState({ rrule: rrule }); this.setState({ rrule: rrule });
} }
public handleCloseToast(_event?: React.SyntheticEvent, reason?: string) {
if (reason === 'clickaway') {
return;
}
this.setState({ error: '' });
}
public onSubmit(e: React.FormEvent<any>) { public onSubmit(e: React.FormEvent<any>) {
e.preventDefault(); e.preventDefault();
@ -279,9 +290,9 @@ class EventEdit extends React.PureComponent<PropsType> {
(by editing the first instance) is supported. (by editing the first instance) is supported.
</div> </div>
)} )}
{this.state.error && ( <Toast open={!!this.state.error} onClose={this.handleCloseToast}>
<div>ERROR! {this.state.error}</div> ERROR! {this.state.error}
)} </Toast>
<form style={styles.form} onSubmit={this.onSubmit}> <form style={styles.form} onSubmit={this.onSubmit}>
<TextField <TextField
name="title" name="title"

@ -28,6 +28,7 @@ import DateTimePicker from '../../widgets/DateTimePicker';
import ConfirmationDialog from '../../widgets/ConfirmationDialog'; import ConfirmationDialog from '../../widgets/ConfirmationDialog';
import TimezonePicker from '../../widgets/TimezonePicker'; import TimezonePicker from '../../widgets/TimezonePicker';
import Toast from '../../widgets/Toast';
import { Location } from 'history'; import { Location } from 'history';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
@ -127,6 +128,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
this.handleInputChange = this.handleInputChange.bind(this); this.handleInputChange = this.handleInputChange.bind(this);
this.toggleTime = this.toggleTime.bind(this); this.toggleTime = this.toggleTime.bind(this);
this.onDeleteRequest = this.onDeleteRequest.bind(this); this.onDeleteRequest = this.onDeleteRequest.bind(this);
this.handleCloseToast = this.handleCloseToast.bind(this);
} }
public UNSAFE_componentWillReceiveProps(nextProps: any) { public UNSAFE_componentWillReceiveProps(nextProps: any) {
@ -161,6 +163,14 @@ class TaskEdit extends React.PureComponent<PropsType> {
this.setState({ includeTime: !this.state.includeTime }); this.setState({ includeTime: !this.state.includeTime });
} }
public handleCloseToast(_event?: React.SyntheticEvent, reason?: string) {
if (reason === 'clickaway') {
return;
}
this.setState({ error: '' });
}
public onSubmit(e: React.FormEvent<any>) { public onSubmit(e: React.FormEvent<any>) {
e.preventDefault(); e.preventDefault();
@ -265,9 +275,9 @@ class TaskEdit extends React.PureComponent<PropsType> {
(by editing the first instance) is supported. (by editing the first instance) is supported.
</div> </div>
)} )}
{this.state.error && ( <Toast open={!!this.state.error} onClose={this.handleCloseToast}>
<div>ERROR! {this.state.error}</div> ERROR! {this.state.error}
)} </Toast>
<form style={styles.form} onSubmit={this.onSubmit}> <form style={styles.form} onSubmit={this.onSubmit}>
<TextField <TextField
name="title" name="title"

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: © 2017 EteSync Authors
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import Snackbar from '@material-ui/core/Snackbar';
import Alert from '@material-ui/lab/Alert';
interface PropsType {
open: boolean;
children: React.ReactNode;
onClose?: (event?: React.SyntheticEvent, reason?: string) => void;
}
export default function Toast(props: PropsType) {
const { open, children, onClose } = props;
return (
<Snackbar open={open} onClose={onClose}>
<Alert severity="error" variant="filled" elevation={6} onClose={onClose}>
{children}
</Alert>
</Snackbar>
);
}
Loading…
Cancel
Save