From e8375d6627573e5465d78798ffd9a012d6191e45 Mon Sep 17 00:00:00 2001 From: Gabriel L Martinez Date: Mon, 6 Apr 2020 20:18:14 -0400 Subject: [PATCH 1/4] Display validation errors on NewPassword page --- .../NewPasswordPage.stories.tsx | 4 ++-- .../NewPasswordPage/NewPasswordPage.tsx | 23 ++++++++++++++++--- src/auth/views/NewPassword.tsx | 15 ++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx index 4f6359937..b5578abc1 100644 --- a/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx +++ b/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx @@ -9,8 +9,8 @@ storiesOf("Views / Authentication / Set up a new password", module) .addDecorator(CardDecorator) .addDecorator(Decorator) .add("default", () => ( - undefined} /> + undefined} /> )) .add("loading", () => ( - undefined} /> + undefined} /> )); diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx index 83e003579..119dce750 100644 --- a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx +++ b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx @@ -9,11 +9,20 @@ import Form from "@saleor/components/Form"; import FormSpacer from "@saleor/components/FormSpacer"; 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: { width: "100%" } - }, + }), { name: "NewPasswordPage" } @@ -25,6 +34,7 @@ export interface NewPasswordPageFormData { } export interface NewPasswordPageProps { disabled: boolean; + error: string; onSubmit: (data: NewPasswordPageFormData) => void; } @@ -34,7 +44,7 @@ const initialForm: NewPasswordPageFormData = { }; const NewPasswordPage: React.FC = props => { - const { disabled, onSubmit } = props; + const { disabled, error, onSubmit } = props; const classes = useStyles(props); const intl = useIntl(); @@ -47,6 +57,13 @@ const NewPasswordPage: React.FC = props => { return ( <> + {!!error && ( +
+ + {error} + +
+ )} diff --git a/src/auth/views/NewPassword.tsx b/src/auth/views/NewPassword.tsx index c667f92d0..ddd5cf9da 100644 --- a/src/auth/views/NewPassword.tsx +++ b/src/auth/views/NewPassword.tsx @@ -4,6 +4,9 @@ import { RouteComponentProps } from "react-router"; import useNavigator from "@saleor/hooks/useNavigator"; import useUser from "@saleor/hooks/useUser"; +import { useIntl } from "react-intl"; +import { commonMessages } from "@saleor/intl"; +import getAccountErrorMessage from "@saleor/utils/errors/account"; import NewPasswordPage, { NewPasswordPageFormData } from "../components/NewPasswordPage"; @@ -14,6 +17,8 @@ import { NewPasswordUrlQueryParams } from "../urls"; const NewPassword: React.FC = ({ location }) => { const navigate = useNavigator(); const { loginByToken } = useUser(); + const [error, setError] = React.useState(); + const intl = useIntl(); const params: NewPasswordUrlQueryParams = parseQs(location.search.substr(1)); @@ -21,6 +26,15 @@ const NewPassword: React.FC = ({ location }) => { if (data.setPassword.errors.length === 0) { loginByToken(data.setPassword.token, data.setPassword.user); navigate("/", true); + } else { + const error = data.setPassword.errors.find( + err => err.field === "password" + ); + if (error) { + setError(getAccountErrorMessage(error, intl)); + } else { + setError(intl.formatMessage(commonMessages.somethingWentWrong)); + } } }; @@ -38,6 +52,7 @@ const NewPassword: React.FC = ({ location }) => { return ( From b6930ce7b3c0e82586d1bf75e3eee947f324e5cf Mon Sep 17 00:00:00 2001 From: Gabriel L Martinez Date: Mon, 6 Apr 2020 20:26:42 -0400 Subject: [PATCH 2/4] Updating Changelog file --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c1bda54..dfcb79337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable, unreleased changes to this project will be documented in this file. - Fix crashing views - #422 by @dominik-zeglen - Add "Ready to capture" to the "Status" order filter - #430 by @dominik-zeglen - Reset state after closing - #456 by @dominik-zeglen +- Password validation errors are not shown - #471 by @gabmartinez ## 2.0.0 From 06e78acbf61d8d6cd02312124e8d3626dd4c8147 Mon Sep 17 00:00:00 2001 From: Gabriel L Martinez Date: Tue, 7 Apr 2020 09:29:31 -0400 Subject: [PATCH 3/4] Adding storyshot for password too short error --- .../NewPasswordPage.stories.tsx | 16 ++- .../NewPasswordPage/NewPasswordPage.tsx | 10 +- src/auth/views/NewPassword.tsx | 24 ++-- .../__snapshots__/Stories.test.ts.snap | 127 ++++++++++++++++++ 4 files changed, 158 insertions(+), 19 deletions(-) diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx index b5578abc1..36e2e3cf4 100644 --- a/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx +++ b/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx @@ -3,14 +3,26 @@ import React from "react"; import CardDecorator from "@saleor/storybook//CardDecorator"; import Decorator from "@saleor/storybook//Decorator"; +import { AccountErrorCode } from "@saleor/types/globalTypes"; import NewPasswordPage from "./NewPasswordPage"; storiesOf("Views / Authentication / Set up a new password", module) .addDecorator(CardDecorator) .addDecorator(Decorator) .add("default", () => ( - undefined} /> + undefined} /> )) .add("loading", () => ( - undefined} /> + undefined} /> + )) + .add("too short error", () => ( + ({ + __typename: "AccountError", + code: AccountErrorCode.PASSWORD_TOO_SHORT, + field + }))} + disabled={false} + onSubmit={() => undefined} + /> )); diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx index 119dce750..2dfd65389 100644 --- a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx +++ b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx @@ -7,6 +7,8 @@ import { FormattedMessage, useIntl } from "react-intl"; import Form from "@saleor/components/Form"; 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( theme => ({ @@ -34,7 +36,7 @@ export interface NewPasswordPageFormData { } export interface NewPasswordPageProps { disabled: boolean; - error: string; + errors: SetPassword_setPassword_errors[]; onSubmit: (data: NewPasswordPageFormData) => void; } @@ -44,10 +46,14 @@ const initialForm: NewPasswordPageFormData = { }; const NewPasswordPage: React.FC = props => { - const { disabled, error, onSubmit } = props; + const { disabled, errors, onSubmit } = props; const classes = useStyles(props); const intl = useIntl(); + const error = getAccountErrorMessage( + errors.find(err => err.field === "password"), + intl + ); return (
diff --git a/src/auth/views/NewPassword.tsx b/src/auth/views/NewPassword.tsx index ddd5cf9da..c5ce7b52b 100644 --- a/src/auth/views/NewPassword.tsx +++ b/src/auth/views/NewPassword.tsx @@ -4,21 +4,22 @@ import { RouteComponentProps } from "react-router"; import useNavigator from "@saleor/hooks/useNavigator"; import useUser from "@saleor/hooks/useUser"; -import { useIntl } from "react-intl"; -import { commonMessages } from "@saleor/intl"; -import getAccountErrorMessage from "@saleor/utils/errors/account"; import NewPasswordPage, { NewPasswordPageFormData } from "../components/NewPasswordPage"; import { SetPasswordMutation } from "../mutations"; -import { SetPassword } from "../types/SetPassword"; +import { + SetPassword, + SetPassword_setPassword_errors +} from "../types/SetPassword"; import { NewPasswordUrlQueryParams } from "../urls"; const NewPassword: React.FC = ({ location }) => { const navigate = useNavigator(); const { loginByToken } = useUser(); - const [error, setError] = React.useState(); - const intl = useIntl(); + const [errors, setErrors] = React.useState< + SetPassword_setPassword_errors[] + >(); const params: NewPasswordUrlQueryParams = parseQs(location.search.substr(1)); @@ -27,14 +28,7 @@ const NewPassword: React.FC = ({ location }) => { loginByToken(data.setPassword.token, data.setPassword.user); navigate("/", true); } else { - const error = data.setPassword.errors.find( - err => err.field === "password" - ); - if (error) { - setError(getAccountErrorMessage(error, intl)); - } else { - setError(intl.formatMessage(commonMessages.somethingWentWrong)); - } + setErrors(data.setPassword.errors); } }; @@ -52,7 +46,7 @@ const NewPassword: React.FC = ({ location }) => { return ( diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index 0b8918365..ec5bc21de 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -15166,6 +15166,133 @@ exports[`Storyshots Views / Authentication / Set up a new password loading 1`] = `; +exports[`Storyshots Views / Authentication / Set up a new password too short error 1`] = ` +
+
+
+ +
+
+ This password is too short +
+
+
+ Please set up a new password. +
+
+
+ +
+ + +
+
+
+
+ +
+ + +
+
+
+ + +
+
+
+`; + exports[`Storyshots Views / Authentication / Verifying remembered user default 1`] = `
Date: Tue, 7 Apr 2020 10:00:17 -0400 Subject: [PATCH 4/4] Pass the errors directly to NewPasswordPage component --- src/auth/views/NewPassword.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/auth/views/NewPassword.tsx b/src/auth/views/NewPassword.tsx index c5ce7b52b..b2373720b 100644 --- a/src/auth/views/NewPassword.tsx +++ b/src/auth/views/NewPassword.tsx @@ -8,18 +8,12 @@ import NewPasswordPage, { NewPasswordPageFormData } from "../components/NewPasswordPage"; import { SetPasswordMutation } from "../mutations"; -import { - SetPassword, - SetPassword_setPassword_errors -} from "../types/SetPassword"; +import { SetPassword } from "../types/SetPassword"; import { NewPasswordUrlQueryParams } from "../urls"; const NewPassword: React.FC = ({ location }) => { const navigate = useNavigator(); const { loginByToken } = useUser(); - const [errors, setErrors] = React.useState< - SetPassword_setPassword_errors[] - >(); const params: NewPasswordUrlQueryParams = parseQs(location.search.substr(1)); @@ -27,8 +21,6 @@ const NewPassword: React.FC = ({ location }) => { if (data.setPassword.errors.length === 0) { loginByToken(data.setPassword.token, data.setPassword.user); navigate("/", true); - } else { - setErrors(data.setPassword.errors); } }; @@ -46,7 +38,7 @@ const NewPassword: React.FC = ({ location }) => { return (