Skip to content

Commit dc3c619

Browse files
bexsoftBenjamin Perez
andauthored
Added animation & disabled button / fields on sending (#369)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
1 parent 5000aaf commit dc3c619

File tree

1 file changed

+57
-7
lines changed

1 file changed

+57
-7
lines changed

portal-ui/src/screens/LoginPage/LoginPage.tsx

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,26 @@ import Button from "@material-ui/core/Button";
2222
import TextField from "@material-ui/core/TextField";
2323
import Grid from "@material-ui/core/Grid";
2424
import Typography from "@material-ui/core/Typography";
25-
import { CircularProgress, Paper } from "@material-ui/core";
26-
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
25+
import {
26+
CircularProgress,
27+
LinearProgress,
28+
Paper,
29+
TextFieldProps,
30+
} from "@material-ui/core";
31+
import {
32+
createStyles,
33+
makeStyles,
34+
Theme,
35+
withStyles,
36+
} from "@material-ui/core/styles";
2737
import { SystemState } from "../../types";
2838
import { userLoggedIn } from "../../actions";
2939
import api from "../../common/api";
3040
import { ILoginDetails, loginStrategyType } from "./types";
3141
import { setSession } from "../../common/utils";
3242
import history from "../../history";
43+
import { isBoolean } from "util";
44+
import { OutlinedInputProps } from "@material-ui/core/OutlinedInput";
3345

3446
const styles = (theme: Theme) =>
3547
createStyles({
@@ -121,8 +133,33 @@ const styles = (theme: Theme) =>
121133
jwtInput: {
122134
marginTop: 45,
123135
},
136+
linearPredef: {
137+
height: 10,
138+
},
124139
});
125140

141+
const inputStyles = makeStyles((theme: Theme) =>
142+
createStyles({
143+
disabled: {
144+
"&.MuiInput-underline::before": {
145+
borderColor: "#eaeaea",
146+
borderBottomStyle: "solid",
147+
},
148+
},
149+
})
150+
);
151+
152+
function LoginField(props: TextFieldProps) {
153+
const classes = inputStyles();
154+
155+
return (
156+
<TextField
157+
InputProps={{ classes } as Partial<OutlinedInputProps>}
158+
{...props}
159+
/>
160+
);
161+
}
162+
126163
const mapState = (state: SystemState) => ({
127164
loggedIn: state.loggedIn,
128165
});
@@ -156,6 +193,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
156193
loginStrategy: loginStrategyType.unknown,
157194
redirect: "",
158195
});
196+
const [loginSending, setLoginSending] = useState<boolean>(false);
159197

160198
const loginStrategyEndpoints: LoginStrategyRoutes = {
161199
form: "/api/v1/login",
@@ -180,6 +218,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
180218

181219
const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
182220
e.preventDefault();
221+
setLoginSending(true);
183222
request
184223
.post(
185224
loginStrategyEndpoints[loginStrategy.loginStrategy] || "/api/v1/login"
@@ -191,6 +230,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
191230
// store the jwt token
192231
setSession(bodyResponse.sessionId);
193232
} else if (bodyResponse.error) {
233+
setLoginSending(false);
194234
// throw will be moved to catch block once bad login returns 403
195235
throw bodyResponse.error;
196236
}
@@ -201,6 +241,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
201241
history.push("/");
202242
})
203243
.catch((err) => {
244+
setLoginSending(false);
204245
setError(err.message);
205246
});
206247
};
@@ -225,7 +266,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
225266
<form className={classes.form} noValidate onSubmit={formSubmit}>
226267
<Grid container spacing={2}>
227268
<Grid item xs={12}>
228-
<TextField
269+
<LoginField
229270
fullWidth
230271
id="accessKey"
231272
value={accessKey}
@@ -235,10 +276,11 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
235276
label="Enter Access Key"
236277
name="accessKey"
237278
autoComplete="username"
279+
disabled={loginSending}
238280
/>
239281
</Grid>
240282
<Grid item xs={12}>
241-
<TextField
283+
<LoginField
242284
fullWidth
243285
value={secretKey}
244286
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
@@ -249,6 +291,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
249291
type="password"
250292
id="secretKey"
251293
autoComplete="current-password"
294+
disabled={loginSending}
252295
/>
253296
</Grid>
254297
</Grid>
@@ -258,11 +301,14 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
258301
variant="contained"
259302
color="primary"
260303
className={classes.submit}
261-
disabled={secretKey === "" || accessKey === ""}
304+
disabled={secretKey === "" || accessKey === "" || loginSending}
262305
>
263306
Login
264307
</Button>
265308
</Grid>
309+
<Grid item xs={12} className={classes.linearPredef}>
310+
{loginSending && <LinearProgress />}
311+
</Grid>
266312
<Grid item xs={12} className={classes.disclaimer}>
267313
<strong>Don't have an access key?</strong>
268314
<br />
@@ -314,7 +360,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
314360
<form className={classes.form} noValidate onSubmit={formSubmit}>
315361
<Grid container spacing={2}>
316362
<Grid item xs={12} className={classes.jwtInput}>
317-
<TextField
363+
<LoginField
318364
required
319365
fullWidth
320366
id="jwt"
@@ -325,6 +371,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
325371
label="JWT"
326372
name="jwt"
327373
autoComplete="Service Account JWT Token"
374+
disabled={loginSending}
328375
/>
329376
</Grid>
330377
</Grid>
@@ -334,11 +381,14 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
334381
variant="contained"
335382
color="primary"
336383
className={classes.submit}
337-
disabled={jwt === ""}
384+
disabled={jwt === "" || loginSending}
338385
>
339386
Login
340387
</Button>
341388
</Grid>
389+
<Grid item xs={12} className={classes.linearPredef}>
390+
{loginSending && <LinearProgress />}
391+
</Grid>
342392
<Grid item xs={12} className={classes.disclaimer}>
343393
<strong>Don't have an access key?</strong>
344394
<br />

0 commit comments

Comments
 (0)