Merge pull request #471 from gabmartinez/fix/password-validation-errors-are-not-shown

Display validation errors on NewPassword page
This commit is contained in:
Dominik Żegleń 2020-04-07 16:23:11 +02:00 committed by GitHub
commit 05078112da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 169 additions and 5 deletions

View file

@ -40,6 +40,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Fix crashing views - #422 by @dominik-zeglen - Fix crashing views - #422 by @dominik-zeglen
- Add "Ready to capture" to the "Status" order filter - #430 by @dominik-zeglen - Add "Ready to capture" to the "Status" order filter - #430 by @dominik-zeglen
- Reset state after closing - #456 by @dominik-zeglen - Reset state after closing - #456 by @dominik-zeglen
- Password validation errors are not shown - #471 by @gabmartinez
## 2.0.0 ## 2.0.0

View file

@ -3,14 +3,26 @@ import React from "react";
import CardDecorator from "@saleor/storybook//CardDecorator"; import CardDecorator from "@saleor/storybook//CardDecorator";
import Decorator from "@saleor/storybook//Decorator"; import Decorator from "@saleor/storybook//Decorator";
import { AccountErrorCode } from "@saleor/types/globalTypes";
import NewPasswordPage from "./NewPasswordPage"; import NewPasswordPage from "./NewPasswordPage";
storiesOf("Views / Authentication / Set up a new password", module) storiesOf("Views / Authentication / Set up a new password", module)
.addDecorator(CardDecorator) .addDecorator(CardDecorator)
.addDecorator(Decorator) .addDecorator(Decorator)
.add("default", () => ( .add("default", () => (
<NewPasswordPage disabled={false} onSubmit={() => undefined} /> <NewPasswordPage errors={[]} disabled={false} onSubmit={() => undefined} />
)) ))
.add("loading", () => ( .add("loading", () => (
<NewPasswordPage disabled={true} onSubmit={() => undefined} /> <NewPasswordPage errors={[]} disabled={true} onSubmit={() => undefined} />
))
.add("too short error", () => (
<NewPasswordPage
errors={["password"].map(field => ({
__typename: "AccountError",
code: AccountErrorCode.PASSWORD_TOO_SHORT,
field
}))}
disabled={false}
onSubmit={() => undefined}
/>
)); ));

View file

@ -7,13 +7,24 @@ import { FormattedMessage, useIntl } from "react-intl";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import { SetPassword_setPassword_errors } from "@saleor/auth/types/SetPassword";
import getAccountErrorMessage from "@saleor/utils/errors/account";
const useStyles = makeStyles( const useStyles = makeStyles(
{ theme => ({
errorText: {
color: theme.palette.error.contrastText
},
panel: {
background: theme.palette.error.main,
borderRadius: theme.spacing(),
marginBottom: theme.spacing(3),
padding: theme.spacing(1.5)
},
submit: { submit: {
width: "100%" width: "100%"
} }
}, }),
{ {
name: "NewPasswordPage" name: "NewPasswordPage"
} }
@ -25,6 +36,7 @@ export interface NewPasswordPageFormData {
} }
export interface NewPasswordPageProps { export interface NewPasswordPageProps {
disabled: boolean; disabled: boolean;
errors: SetPassword_setPassword_errors[];
onSubmit: (data: NewPasswordPageFormData) => void; onSubmit: (data: NewPasswordPageFormData) => void;
} }
@ -34,10 +46,14 @@ const initialForm: NewPasswordPageFormData = {
}; };
const NewPasswordPage: React.FC<NewPasswordPageProps> = props => { const NewPasswordPage: React.FC<NewPasswordPageProps> = props => {
const { disabled, onSubmit } = props; const { disabled, errors, onSubmit } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const error = getAccountErrorMessage(
errors.find(err => err.field === "password"),
intl
);
return ( return (
<Form initial={initialForm} onSubmit={onSubmit}> <Form initial={initialForm} onSubmit={onSubmit}>
@ -47,6 +63,13 @@ const NewPasswordPage: React.FC<NewPasswordPageProps> = props => {
return ( return (
<> <>
{!!error && (
<div className={classes.panel}>
<Typography variant="caption" className={classes.errorText}>
{error}
</Typography>
</div>
)}
<Typography> <Typography>
<FormattedMessage defaultMessage="Please set up a new password." /> <FormattedMessage defaultMessage="Please set up a new password." />
</Typography> </Typography>

View file

@ -38,6 +38,7 @@ const NewPassword: React.FC<RouteComponentProps> = ({ location }) => {
return ( return (
<NewPasswordPage <NewPasswordPage
errors={setPasswordOpts.data?.setPassword.errors || []}
disabled={setPasswordOpts.loading} disabled={setPasswordOpts.loading}
onSubmit={handleSubmit} onSubmit={handleSubmit}
/> />

View file

@ -15166,6 +15166,133 @@ exports[`Storyshots Views / Authentication / Set up a new password loading 1`] =
</div> </div>
`; `;
exports[`Storyshots Views / Authentication / Set up a new password too short error 1`] = `
<div
style="padding:24px"
>
<div
class="MuiPaper-root-id MuiPaper-elevation0-id MuiCard-root-id MuiPaper-rounded-id"
style="margin:auto;overflow:visible;position:relative;width:400px"
>
<div
class="MuiCardContent-root-id"
>
<form>
<div
class="NewPasswordPage-panel-id"
>
<div
class="MuiTypography-root-id NewPasswordPage-errorText-id MuiTypography-caption-id"
>
This password is too short
</div>
</div>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
Please set up a new password.
</div>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id"
data-shrink="false"
>
New Password
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
autocomplete="none"
autofocus=""
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
data-tc="password"
name="password"
type="password"
value=""
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0.01px"
>
<span>
</span>
</legend>
</fieldset>
</div>
</div>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id"
data-shrink="false"
>
Confirm Password
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
autocomplete="none"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
data-tc="confirm-password"
name="confirmPassword"
type="password"
value=""
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0.01px"
>
<span>
</span>
</legend>
</fieldset>
</div>
</div>
<div
class="FormSpacer-spacer-id"
/>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id NewPasswordPage-submit-id MuiButton-containedPrimary-id"
tabindex="0"
type="submit"
>
<span
class="MuiButton-label-id"
>
Set new password
</span>
</button>
</form>
</div>
</div>
</div>
`;
exports[`Storyshots Views / Authentication / Verifying remembered user default 1`] = ` exports[`Storyshots Views / Authentication / Verifying remembered user default 1`] = `
<div <div
style="padding:24px" style="padding:24px"