Added animation & disabled button / fields on sending (#369)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -22,14 +22,26 @@ import Button from "@material-ui/core/Button";
|
|||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import { CircularProgress, Paper } from "@material-ui/core";
|
import {
|
||||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
CircularProgress,
|
||||||
|
LinearProgress,
|
||||||
|
Paper,
|
||||||
|
TextFieldProps,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import {
|
||||||
|
createStyles,
|
||||||
|
makeStyles,
|
||||||
|
Theme,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core/styles";
|
||||||
import { SystemState } from "../../types";
|
import { SystemState } from "../../types";
|
||||||
import { userLoggedIn } from "../../actions";
|
import { userLoggedIn } from "../../actions";
|
||||||
import api from "../../common/api";
|
import api from "../../common/api";
|
||||||
import { ILoginDetails, loginStrategyType } from "./types";
|
import { ILoginDetails, loginStrategyType } from "./types";
|
||||||
import { setSession } from "../../common/utils";
|
import { setSession } from "../../common/utils";
|
||||||
import history from "../../history";
|
import history from "../../history";
|
||||||
|
import { isBoolean } from "util";
|
||||||
|
import { OutlinedInputProps } from "@material-ui/core/OutlinedInput";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
@@ -121,8 +133,33 @@ const styles = (theme: Theme) =>
|
|||||||
jwtInput: {
|
jwtInput: {
|
||||||
marginTop: 45,
|
marginTop: 45,
|
||||||
},
|
},
|
||||||
|
linearPredef: {
|
||||||
|
height: 10,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inputStyles = makeStyles((theme: Theme) =>
|
||||||
|
createStyles({
|
||||||
|
disabled: {
|
||||||
|
"&.MuiInput-underline::before": {
|
||||||
|
borderColor: "#eaeaea",
|
||||||
|
borderBottomStyle: "solid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
function LoginField(props: TextFieldProps) {
|
||||||
|
const classes = inputStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
InputProps={{ classes } as Partial<OutlinedInputProps>}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const mapState = (state: SystemState) => ({
|
const mapState = (state: SystemState) => ({
|
||||||
loggedIn: state.loggedIn,
|
loggedIn: state.loggedIn,
|
||||||
});
|
});
|
||||||
@@ -156,6 +193,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
loginStrategy: loginStrategyType.unknown,
|
loginStrategy: loginStrategyType.unknown,
|
||||||
redirect: "",
|
redirect: "",
|
||||||
});
|
});
|
||||||
|
const [loginSending, setLoginSending] = useState<boolean>(false);
|
||||||
|
|
||||||
const loginStrategyEndpoints: LoginStrategyRoutes = {
|
const loginStrategyEndpoints: LoginStrategyRoutes = {
|
||||||
form: "/api/v1/login",
|
form: "/api/v1/login",
|
||||||
@@ -180,6 +218,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
|
|
||||||
const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
setLoginSending(true);
|
||||||
request
|
request
|
||||||
.post(
|
.post(
|
||||||
loginStrategyEndpoints[loginStrategy.loginStrategy] || "/api/v1/login"
|
loginStrategyEndpoints[loginStrategy.loginStrategy] || "/api/v1/login"
|
||||||
@@ -191,6 +230,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
// store the jwt token
|
// store the jwt token
|
||||||
setSession(bodyResponse.sessionId);
|
setSession(bodyResponse.sessionId);
|
||||||
} else if (bodyResponse.error) {
|
} else if (bodyResponse.error) {
|
||||||
|
setLoginSending(false);
|
||||||
// throw will be moved to catch block once bad login returns 403
|
// throw will be moved to catch block once bad login returns 403
|
||||||
throw bodyResponse.error;
|
throw bodyResponse.error;
|
||||||
}
|
}
|
||||||
@@ -201,6 +241,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
history.push("/");
|
history.push("/");
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
setLoginSending(false);
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -225,7 +266,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
<form className={classes.form} noValidate onSubmit={formSubmit}>
|
<form className={classes.form} noValidate onSubmit={formSubmit}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<TextField
|
<LoginField
|
||||||
fullWidth
|
fullWidth
|
||||||
id="accessKey"
|
id="accessKey"
|
||||||
value={accessKey}
|
value={accessKey}
|
||||||
@@ -235,10 +276,11 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
label="Enter Access Key"
|
label="Enter Access Key"
|
||||||
name="accessKey"
|
name="accessKey"
|
||||||
autoComplete="username"
|
autoComplete="username"
|
||||||
|
disabled={loginSending}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<TextField
|
<LoginField
|
||||||
fullWidth
|
fullWidth
|
||||||
value={secretKey}
|
value={secretKey}
|
||||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
@@ -249,6 +291,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
type="password"
|
type="password"
|
||||||
id="secretKey"
|
id="secretKey"
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
|
disabled={loginSending}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -258,11 +301,14 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
className={classes.submit}
|
className={classes.submit}
|
||||||
disabled={secretKey === "" || accessKey === ""}
|
disabled={secretKey === "" || accessKey === "" || loginSending}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item xs={12} className={classes.linearPredef}>
|
||||||
|
{loginSending && <LinearProgress />}
|
||||||
|
</Grid>
|
||||||
<Grid item xs={12} className={classes.disclaimer}>
|
<Grid item xs={12} className={classes.disclaimer}>
|
||||||
<strong>Don't have an access key?</strong>
|
<strong>Don't have an access key?</strong>
|
||||||
<br />
|
<br />
|
||||||
@@ -314,7 +360,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
<form className={classes.form} noValidate onSubmit={formSubmit}>
|
<form className={classes.form} noValidate onSubmit={formSubmit}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12} className={classes.jwtInput}>
|
<Grid item xs={12} className={classes.jwtInput}>
|
||||||
<TextField
|
<LoginField
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
id="jwt"
|
id="jwt"
|
||||||
@@ -325,6 +371,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
label="JWT"
|
label="JWT"
|
||||||
name="jwt"
|
name="jwt"
|
||||||
autoComplete="Service Account JWT Token"
|
autoComplete="Service Account JWT Token"
|
||||||
|
disabled={loginSending}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -334,11 +381,14 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
className={classes.submit}
|
className={classes.submit}
|
||||||
disabled={jwt === ""}
|
disabled={jwt === "" || loginSending}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item xs={12} className={classes.linearPredef}>
|
||||||
|
{loginSending && <LinearProgress />}
|
||||||
|
</Grid>
|
||||||
<Grid item xs={12} className={classes.disclaimer}>
|
<Grid item xs={12} className={classes.disclaimer}>
|
||||||
<strong>Don't have an access key?</strong>
|
<strong>Don't have an access key?</strong>
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
Reference in New Issue
Block a user