Repository: mirumee/saleor-dashboard (ts)

Issue:
Password validation errors are not shown
### What I'm trying to achieve
To set password as a new staff user.

### Steps to reproduce the problem
1. Create a new staff user through the dashboard.
2. Receive an email with the link to set up password and click it.
3. Provide a password that doesn't validate against password rules, e.g. too short.

### What I expected to happen
To see a validation error.

### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
![image](https://user-images.githubusercontent.com/5421321/78534243-62b05f80-77ea-11ea-9a96-e7c2a476eb84.png)



Pull request:
Display validation errors on NewPassword page
I want to merge this change because it displays the validation errors on the New Password Page.

fix #468 
<!-- Please mention all relevant issue numbers. -->

### Screenshots

<!-- If your changes affect the UI, providing "before" and "after" screenshots will
greatly reduce the amount of work needed to review your work. -->

### Pull Request Checklist

<!-- Please keep this section. It will make maintainer's life easier. -->

1. [x] All visible strings are translated with proper context.
1. [x] All data-formatting is locale-aware (dates, numbers, and so on).
1. [x] Translated strings are extracted.
1. [x] Number of API calls is optimized.
1. [x] The changes are tested.
1. [x] Type definitions are up to date.
1. [x] Changes are mentioned in the changelog.


Patch:
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
 
diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.stories.tsx
index 4f6359937..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", () => (
-    <NewPasswordPage disabled={false} onSubmit={() => undefined} />
+    <NewPasswordPage errors={[]} disabled={false} onSubmit={() => undefined} />
   ))
   .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}
+    />
   ));
diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
index 83e003579..2dfd65389 100644
--- a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
+++ b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
@@ -7,13 +7,24 @@ 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 => ({
+    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 +36,7 @@ export interface NewPasswordPageFormData {
 }
 export interface NewPasswordPageProps {
   disabled: boolean;
+  errors: SetPassword_setPassword_errors[];
   onSubmit: (data: NewPasswordPageFormData) => void;
 }
 
@@ -34,10 +46,14 @@ const initialForm: NewPasswordPageFormData = {
 };
 
 const NewPasswordPage: React.FC<NewPasswordPageProps> = props => {
-  const { disabled, 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 (
     <Form initial={initialForm} onSubmit={onSubmit}>
@@ -47,6 +63,13 @@ const NewPasswordPage: React.FC<NewPasswordPageProps> = props => {
 
         return (
           <>
+            {!!error && (
+              <div className={classes.panel}>
+                <Typography variant="caption" className={classes.errorText}>
+                  {error}
+                </Typography>
+              </div>
+            )}
             <Typography>
               <FormattedMessage defaultMessage="Please set up a new password." />
             </Typography>
diff --git a/src/auth/views/NewPassword.tsx b/src/auth/views/NewPassword.tsx
index c667f92d0..b2373720b 100644
--- a/src/auth/views/NewPassword.tsx
+++ b/src/auth/views/NewPassword.tsx
@@ -38,6 +38,7 @@ const NewPassword: React.FC<RouteComponentProps> = ({ location }) => {
 
         return (
           <NewPasswordPage
+            errors={setPasswordOpts.data?.setPassword.errors || []}
             disabled={setPasswordOpts.loading}
             onSubmit={handleSubmit}
           />


Test patch:
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`] =
 </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`] = `
 <div
   style="padding:24px"