From 6ae13b12f12ee54e93e3af64002f1fcf7c5efd79 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Tue, 26 Jul 2022 23:00:48 +0000 Subject: [PATCH 1/5] fix: show errors on SSH Key page --- .../SSHKeysPage/SSHKeysPage.test.tsx | 2 +- .../SSHKeysPage/SSHKeysPage.tsx | 48 ++++++++++++------- site/src/xServices/auth/authXService.ts | 8 +--- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx index 01c1ac82dada7..b44136a415793 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx @@ -85,7 +85,7 @@ describe("SSH keys Page", () => { fireEvent.click(confirmButton) // Check if the error message is displayed - await screen.findByText(authXServiceLanguage.errorRegenerateSSHKey) + await screen.findByText(SSHKeysPageLanguage.errorRegenerateSSHKey) // Check if the API was called correctly expect(API.regenerateUserSSHKey).toBeCalledTimes(1) diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx index 14beb82fe6379..ce15d0fcbbe52 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx @@ -2,6 +2,7 @@ import Box from "@material-ui/core/Box" import Button from "@material-ui/core/Button" import CircularProgress from "@material-ui/core/CircularProgress" import { useActor } from "@xstate/react" +import { ErrorSummary } from "components/ErrorSummary/ErrorSummary" import React, { useContext, useEffect } from "react" import { CodeExample } from "../../../components/CodeExample/CodeExample" import { ConfirmDialog } from "../../../components/ConfirmDialog/ConfirmDialog" @@ -19,12 +20,13 @@ export const Language = { "You will need to replace the public SSH key on services you use it with, and you'll need to rebuild existing workspaces.", confirmLabel: "Confirm", cancelLabel: "Cancel", + errorRegenerateSSHKey: "Error on regenerate the SSH Key", } export const SSHKeysPage: React.FC = () => { const xServices = useContext(XServiceContext) const [authState, authSend] = useActor(xServices.authXService) - const { sshKey } = authState.context + const { sshKey, getSSHKeyError, regenerateSSHKeyError } = authState.context useEffect(() => { authSend({ type: "GET_SSH_KEY" }) @@ -33,27 +35,39 @@ export const SSHKeysPage: React.FC = () => { return ( <>
- {!sshKey && ( + {authState.matches("signedIn.ssh.gettingSSHKey") && ( )} - {sshKey && ( - - -
- -
-
- )} + + {/* Regenerating the key is not an option if getSSHKey fails. + Only one of the error messages will exist at a single time */} + {getSSHKeyError && } + {regenerateSSHKeyError && ( + + )} + {authState.matches("signedIn.ssh.loaded") && sshKey && ( + <> + +
+ +
+ + )} +
{ displaySuccess(Language.successRegenerateSSHKey) }, - notifySSHKeyRegenerationError: () => { - displayError(Language.errorRegenerateSSHKey) - }, }, }, ) From c37b4ece6d679fa8daae315b52f8d899c756db4e Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Tue, 26 Jul 2022 23:53:01 +0000 Subject: [PATCH 2/5] handle all auth api errors --- .../SignInForm/SignInForm.stories.tsx | 79 ++++++++++++++++--- site/src/components/SignInForm/SignInForm.tsx | 48 ++++++++--- site/src/pages/LoginPage/LoginPage.tsx | 10 ++- site/src/xServices/auth/authXService.ts | 3 +- 4 files changed, 114 insertions(+), 26 deletions(-) diff --git a/site/src/components/SignInForm/SignInForm.stories.tsx b/site/src/components/SignInForm/SignInForm.stories.tsx index 7e6b24f79ed2a..96cc39cde5c30 100644 --- a/site/src/components/SignInForm/SignInForm.stories.tsx +++ b/site/src/components/SignInForm/SignInForm.stories.tsx @@ -15,7 +15,7 @@ const Template: Story = (args: SignInFormProps) => { return Promise.resolve() }, @@ -34,29 +34,82 @@ Loading.args = { export const WithLoginError = Template.bind({}) WithLoginError.args = { ...SignedOut.args, - authError: { - response: { - data: { - message: "Email or password was invalid", - validations: [ - { - field: "password", - detail: "Password is invalid.", - }, - ], + loginErrors: { + authError: { + response: { + data: { + message: "Email or password was invalid", + validations: [ + { + field: "password", + detail: "Password is invalid.", + }, + ], + }, }, + isAxiosError: true, }, - isAxiosError: true, }, initialTouched: { password: true, }, } +export const WithGetUserError = Template.bind({}) +WithGetUserError.args = { + ...SignedOut.args, + loginErrors: { + getUserError: { + response: { + data: { + message: "Unable to fetch user details", + detail: "Resource not found or you do not have access to this resource.", + }, + }, + isAxiosError: true, + }, + }, +} + +export const WithCheckPermissionsError = Template.bind({}) +WithCheckPermissionsError.args = { + ...SignedOut.args, + loginErrors: { + checkPermissionsError: { + response: { + data: { + message: "Unable to fetch user permissions", + detail: "Resource not found or you do not have access to this resource.", + }, + }, + isAxiosError: true, + }, + }, +} + export const WithAuthMethodsError = Template.bind({}) WithAuthMethodsError.args = { ...SignedOut.args, - methodsError: new Error("Failed to fetch auth methods"), + loginErrors: { + getMethodsError: new Error("Failed to fetch auth methods"), + }, +} + +export const WithGetUserAndAuthMethodsErrors = Template.bind({}) +WithGetUserAndAuthMethodsErrors.args = { + ...SignedOut.args, + loginErrors: { + getUserError: { + response: { + data: { + message: "Unable to fetch user details", + detail: "Resource not found or you do not have access to this resource.", + }, + }, + isAxiosError: true, + }, + getMethodsError: new Error("Failed to fetch auth methods"), + }, } export const WithGithub = Template.bind({}) diff --git a/site/src/components/SignInForm/SignInForm.tsx b/site/src/components/SignInForm/SignInForm.tsx index bfa28ca8bd3cb..3bdfee507fc6a 100644 --- a/site/src/components/SignInForm/SignInForm.tsx +++ b/site/src/components/SignInForm/SignInForm.tsx @@ -29,7 +29,9 @@ export const Language = { emailInvalid: "Please enter a valid email address.", emailRequired: "Please enter an email address.", authErrorMessage: "Incorrect email or password.", - methodsErrorMessage: "Unable to fetch auth methods.", + getUserErrorMessage: "Unable to fetch user details.", + checkPermissionsErrorMessage: "Unable to fetch user permissions.", + getMethodsErrorMessage: "Unable to fetch auth methods.", passwordSignIn: "Sign In", githubSignIn: "GitHub", } @@ -65,11 +67,17 @@ const useStyles = makeStyles((theme) => ({ }, })) +type LoginErrors = { + authError?: Error | unknown + getUserError?: Error | unknown + checkPermissionsError?: Error | unknown + getMethodsError?: Error | unknown +} + export interface SignInFormProps { isLoading: boolean redirectTo: string - authError?: Error | unknown - methodsError?: Error | unknown + loginErrors: LoginErrors authMethods?: AuthMethods onSubmit: ({ email, password }: { email: string; password: string }) => Promise // initialTouched is only used for testing the error state of the form. @@ -80,8 +88,7 @@ export const SignInForm: FC = ({ authMethods, redirectTo, isLoading, - authError, - methodsError, + loginErrors, onSubmit, initialTouched, }) => { @@ -101,18 +108,39 @@ export const SignInForm: FC = ({ onSubmit, initialTouched, }) - const getFieldHelpers = getFormHelpersWithError(form, authError) + const getFieldHelpers = getFormHelpersWithError( + form, + loginErrors.authError, + ) return ( <>
- {authError && ( - + {loginErrors.authError && ( + + )} + {loginErrors.getUserError && ( + + )} + {loginErrors.checkPermissionsError && ( + )} - {methodsError && ( - + {loginErrors.getMethodsError && ( + )} { authSend({ type: "SIGN_IN", email, password }) } + const { authError, getUserError, checkPermissionsError, getMethodsError } = authState.context + if (authState.matches("signedIn")) { return } else { @@ -54,8 +56,12 @@ export const LoginPage: React.FC = () => { authMethods={authState.context.methods} redirectTo={redirectTo} isLoading={isLoading} - authError={authState.context.authError} - methodsError={authState.context.getMethodsError as Error} + loginErrors={{ + authError, + getUserError, + checkPermissionsError, + getMethodsError, + }} onSubmit={onSubmit} /> diff --git a/site/src/xServices/auth/authXService.ts b/site/src/xServices/auth/authXService.ts index c68e23cce1be0..cf0a9432ea33a 100644 --- a/site/src/xServices/auth/authXService.ts +++ b/site/src/xServices/auth/authXService.ts @@ -213,12 +213,13 @@ export const authMachine = tags: "loading", }, gettingUser: { + entry: "clearGetUserError", invoke: { src: "getMe", id: "getMe", onDone: [ { - actions: ["assignMe", "clearGetUserError"], + actions: ["assignMe"], target: "gettingPermissions", }, ], From 865c1c50d33f1e7ad9edefd51b1d7dca45c78687 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 28 Jul 2022 09:06:07 +0000 Subject: [PATCH 3/5] add stories, refactor code --- site/src/components/SignInForm/SignInForm.tsx | 57 +++++++---------- site/src/pages/LoginPage/LoginPage.test.tsx | 4 +- .../SSHKeysPage/SSHKeysPage.test.tsx | 7 +- .../SSHKeysPage/SSHKeysPage.tsx | 57 +++++------------ .../SSHKeysPage/SSHKeysPageView.stories.tsx | 62 ++++++++++++++++++ .../SSHKeysPage/SSHKeysPageView.tsx | 64 +++++++++++++++++++ 6 files changed, 170 insertions(+), 81 deletions(-) create mode 100644 site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx create mode 100644 site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx diff --git a/site/src/components/SignInForm/SignInForm.tsx b/site/src/components/SignInForm/SignInForm.tsx index 3bdfee507fc6a..94f6c5a3fdc39 100644 --- a/site/src/components/SignInForm/SignInForm.tsx +++ b/site/src/components/SignInForm/SignInForm.tsx @@ -23,15 +23,24 @@ interface BuiltInAuthFormValues { password: string } +export enum LoginErrors { + AUTH_ERROR = "authError", + GET_USER_ERROR = "getUserError", + CHECK_PERMISSIONS_ERROR = "checkPermissionsError", + GET_METHODS_ERROR = "getMethodsError", +} + export const Language = { emailLabel: "Email", passwordLabel: "Password", emailInvalid: "Please enter a valid email address.", emailRequired: "Please enter an email address.", - authErrorMessage: "Incorrect email or password.", - getUserErrorMessage: "Unable to fetch user details.", - checkPermissionsErrorMessage: "Unable to fetch user permissions.", - getMethodsErrorMessage: "Unable to fetch auth methods.", + errorMessages: { + [LoginErrors.AUTH_ERROR]: "Incorrect email or password.", + [LoginErrors.GET_USER_ERROR]: "Unable to fetch user details.", + [LoginErrors.CHECK_PERMISSIONS_ERROR]: "Unable to fetch user permissions.", + [LoginErrors.GET_METHODS_ERROR]: "Unable to fetch auth methods.", + }, passwordSignIn: "Sign In", githubSignIn: "GitHub", } @@ -67,17 +76,10 @@ const useStyles = makeStyles((theme) => ({ }, })) -type LoginErrors = { - authError?: Error | unknown - getUserError?: Error | unknown - checkPermissionsError?: Error | unknown - getMethodsError?: Error | unknown -} - export interface SignInFormProps { isLoading: boolean redirectTo: string - loginErrors: LoginErrors + loginErrors: Record authMethods?: AuthMethods onSubmit: ({ email, password }: { email: string; password: string }) => Promise // initialTouched is only used for testing the error state of the form. @@ -118,29 +120,14 @@ export const SignInForm: FC = ({ - {loginErrors.authError && ( - - )} - {loginErrors.getUserError && ( - - )} - {loginErrors.checkPermissionsError && ( - - )} - {loginErrors.getMethodsError && ( - + {Object.keys(loginErrors).map((errorKey: string) => + loginErrors[errorKey as LoginErrors] ? ( + + ) : null, )} { server.use( // Make login fail rest.post("/api/v2/users/login", async (req, res, ctx) => { - return res(ctx.status(500), ctx.json({ message: Language.authErrorMessage })) + return res(ctx.status(500), ctx.json({ message: Language.errorMessages.authError })) }), ) @@ -45,7 +45,7 @@ describe("LoginPage", () => { act(() => signInButton.click()) // Then - const errorMessage = await screen.findByText(Language.authErrorMessage) + const errorMessage = await screen.findByText(Language.errorMessages.authError) expect(errorMessage).toBeDefined() expect(history.location.pathname).toEqual("/login") }) diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx index b44136a415793..0fbde8225a9e0 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx @@ -4,6 +4,7 @@ import { GlobalSnackbar } from "../../../components/GlobalSnackbar/GlobalSnackba import { MockGitSSHKey, renderWithAuth } from "../../../testHelpers/renderHelpers" import { Language as authXServiceLanguage } from "../../../xServices/auth/authXService" import { Language as SSHKeysPageLanguage, SSHKeysPage } from "./SSHKeysPage" +import { Language as SSHKeysPageViewLanguage } from "./SSHKeysPageView" describe("SSH keys Page", () => { it("shows the SSH key", async () => { @@ -26,7 +27,7 @@ describe("SSH keys Page", () => { // Click on the "Regenerate" button to display the confirm dialog const regenerateButton = screen.getByRole("button", { - name: SSHKeysPageLanguage.regenerateLabel, + name: SSHKeysPageViewLanguage.regenerateLabel, }) fireEvent.click(regenerateButton) const confirmDialog = screen.getByRole("dialog") @@ -72,7 +73,7 @@ describe("SSH keys Page", () => { // Click on the "Regenerate" button to display the confirm dialog const regenerateButton = screen.getByRole("button", { - name: SSHKeysPageLanguage.regenerateLabel, + name: SSHKeysPageViewLanguage.regenerateLabel, }) fireEvent.click(regenerateButton) const confirmDialog = screen.getByRole("dialog") @@ -85,7 +86,7 @@ describe("SSH keys Page", () => { fireEvent.click(confirmButton) // Check if the error message is displayed - await screen.findByText(SSHKeysPageLanguage.errorRegenerateSSHKey) + await screen.findByText(SSHKeysPageViewLanguage.errorRegenerateSSHKey) // Check if the API was called correctly expect(API.regenerateUserSSHKey).toBeCalledTimes(1) diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx index ce15d0fcbbe52..fcb008a6c0655 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.tsx @@ -1,26 +1,19 @@ -import Box from "@material-ui/core/Box" -import Button from "@material-ui/core/Button" -import CircularProgress from "@material-ui/core/CircularProgress" import { useActor } from "@xstate/react" -import { ErrorSummary } from "components/ErrorSummary/ErrorSummary" import React, { useContext, useEffect } from "react" -import { CodeExample } from "../../../components/CodeExample/CodeExample" import { ConfirmDialog } from "../../../components/ConfirmDialog/ConfirmDialog" import { Section } from "../../../components/Section/Section" -import { Stack } from "../../../components/Stack/Stack" import { XServiceContext } from "../../../xServices/StateContext" +import { SSHKeysPageView } from "./SSHKeysPageView" export const Language = { title: "SSH keys", description: "Coder automatically inserts a private key into every workspace; you can add the corresponding public key to any services (such as Git) that you need access to from your workspace.", - regenerateLabel: "Regenerate", regenerateDialogTitle: "Regenerate SSH key?", regenerateDialogMessage: "You will need to replace the public SSH key on services you use it with, and you'll need to rebuild existing workspaces.", confirmLabel: "Confirm", cancelLabel: "Cancel", - errorRegenerateSSHKey: "Error on regenerate the SSH Key", } export const SSHKeysPage: React.FC = () => { @@ -32,42 +25,24 @@ export const SSHKeysPage: React.FC = () => { authSend({ type: "GET_SSH_KEY" }) }, [authSend]) + const isLoading = authState.matches("signedIn.ssh.gettingSSHKey") + const hasLoaded = authState.matches("signedIn.ssh.loaded") + + const onRegenerateClick = () => { + authSend({ type: "REGENERATE_SSH_KEY" }) + } + return ( <>
- {authState.matches("signedIn.ssh.gettingSSHKey") && ( - - - - )} - - - {/* Regenerating the key is not an option if getSSHKey fails. - Only one of the error messages will exist at a single time */} - {getSSHKeyError && } - {regenerateSSHKeyError && ( - - )} - {authState.matches("signedIn.ssh.loaded") && sshKey && ( - <> - -
- -
- - )} -
+
= (args: SSHKeysPageViewProps) => ( + +) + +export const Example = Template.bind({}) +Example.args = { + isLoading: false, + hasLoaded: true, + sshKey: { + user_id: "test-user-id", + created_at: "2022-07-28T07:45:50.795918897Z", + updated_at: "2022-07-28T07:45:50.795919142Z", + public_key: "SSH-Key", + }, + onRegenerateClick: () => { + return Promise.resolve() + }, +} + +export const Loading = Template.bind({}) +Loading.args = { + ...Example.args, + isLoading: true, +} + +export const WithGetSSHKeyError = Template.bind({}) +WithGetSSHKeyError.args = { + ...Example.args, + hasLoaded: false, + getSSHKeyError: { + response: { + data: { + message: "Failed to get SSH key", + }, + }, + isAxiosError: true, + }, +} + +export const WithRegenerateSSHKeyError = Template.bind({}) +WithRegenerateSSHKeyError.args = { + ...Example.args, + regenerateSSHKeyError: { + response: { + data: { + message: "Failed to regenerate SSH key", + }, + }, + isAxiosError: true, + }, +} diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx new file mode 100644 index 0000000000000..9aa135bcf6956 --- /dev/null +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.tsx @@ -0,0 +1,64 @@ +import Box from "@material-ui/core/Box" +import Button from "@material-ui/core/Button" +import CircularProgress from "@material-ui/core/CircularProgress" +import { GitSSHKey } from "api/typesGenerated" +import { CodeExample } from "components/CodeExample/CodeExample" +import { ErrorSummary } from "components/ErrorSummary/ErrorSummary" +import { Stack } from "components/Stack/Stack" +import { FC } from "react" + +export const Language = { + errorRegenerateSSHKey: "Error on regenerating the SSH Key", + regenerateLabel: "Regenerate", +} + +export interface SSHKeysPageViewProps { + isLoading: boolean + hasLoaded: boolean + getSSHKeyError?: Error | unknown + regenerateSSHKeyError?: Error | unknown + sshKey?: GitSSHKey + onRegenerateClick: () => void +} + +export const SSHKeysPageView: FC = ({ + isLoading, + hasLoaded, + getSSHKeyError, + regenerateSSHKeyError, + sshKey, + onRegenerateClick, +}) => { + if (isLoading) { + return ( + + + + ) + } + + return ( + + {/* Regenerating the key is not an option if getSSHKey fails. + Only one of the error messages will exist at a single time */} + {getSSHKeyError && } + {regenerateSSHKeyError && ( + + )} + {hasLoaded && sshKey && ( + <> + +
+ +
+ + )} +
+ ) +} From 3ce260ac8b06920c7d22eeed163c72cb351c2cb3 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 28 Jul 2022 21:01:29 +0000 Subject: [PATCH 4/5] remove getUserError --- .../SignInForm/SignInForm.stories.tsx | 41 ++----------------- site/src/components/SignInForm/SignInForm.tsx | 4 +- site/src/pages/LoginPage/LoginPage.tsx | 3 +- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/site/src/components/SignInForm/SignInForm.stories.tsx b/site/src/components/SignInForm/SignInForm.stories.tsx index 96cc39cde5c30..b32449af64f55 100644 --- a/site/src/components/SignInForm/SignInForm.stories.tsx +++ b/site/src/components/SignInForm/SignInForm.stories.tsx @@ -1,5 +1,5 @@ import { Story } from "@storybook/react" -import { SignInForm, SignInFormProps } from "./SignInForm" +import { LoginErrors, SignInForm, SignInFormProps } from "./SignInForm" export default { title: "components/SignInForm", @@ -35,7 +35,7 @@ export const WithLoginError = Template.bind({}) WithLoginError.args = { ...SignedOut.args, loginErrors: { - authError: { + [LoginErrors.AUTH_ERROR]: { response: { data: { message: "Email or password was invalid", @@ -55,27 +55,11 @@ WithLoginError.args = { }, } -export const WithGetUserError = Template.bind({}) -WithGetUserError.args = { - ...SignedOut.args, - loginErrors: { - getUserError: { - response: { - data: { - message: "Unable to fetch user details", - detail: "Resource not found or you do not have access to this resource.", - }, - }, - isAxiosError: true, - }, - }, -} - export const WithCheckPermissionsError = Template.bind({}) WithCheckPermissionsError.args = { ...SignedOut.args, loginErrors: { - checkPermissionsError: { + [LoginErrors.CHECK_PERMISSIONS_ERROR]: { response: { data: { message: "Unable to fetch user permissions", @@ -91,24 +75,7 @@ export const WithAuthMethodsError = Template.bind({}) WithAuthMethodsError.args = { ...SignedOut.args, loginErrors: { - getMethodsError: new Error("Failed to fetch auth methods"), - }, -} - -export const WithGetUserAndAuthMethodsErrors = Template.bind({}) -WithGetUserAndAuthMethodsErrors.args = { - ...SignedOut.args, - loginErrors: { - getUserError: { - response: { - data: { - message: "Unable to fetch user details", - detail: "Resource not found or you do not have access to this resource.", - }, - }, - isAxiosError: true, - }, - getMethodsError: new Error("Failed to fetch auth methods"), + [LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"), }, } diff --git a/site/src/components/SignInForm/SignInForm.tsx b/site/src/components/SignInForm/SignInForm.tsx index 94f6c5a3fdc39..a4d75dad63dd7 100644 --- a/site/src/components/SignInForm/SignInForm.tsx +++ b/site/src/components/SignInForm/SignInForm.tsx @@ -25,7 +25,6 @@ interface BuiltInAuthFormValues { export enum LoginErrors { AUTH_ERROR = "authError", - GET_USER_ERROR = "getUserError", CHECK_PERMISSIONS_ERROR = "checkPermissionsError", GET_METHODS_ERROR = "getMethodsError", } @@ -37,7 +36,6 @@ export const Language = { emailRequired: "Please enter an email address.", errorMessages: { [LoginErrors.AUTH_ERROR]: "Incorrect email or password.", - [LoginErrors.GET_USER_ERROR]: "Unable to fetch user details.", [LoginErrors.CHECK_PERMISSIONS_ERROR]: "Unable to fetch user permissions.", [LoginErrors.GET_METHODS_ERROR]: "Unable to fetch auth methods.", }, @@ -79,7 +77,7 @@ const useStyles = makeStyles((theme) => ({ export interface SignInFormProps { isLoading: boolean redirectTo: string - loginErrors: Record + loginErrors: Partial> authMethods?: AuthMethods onSubmit: ({ email, password }: { email: string; password: string }) => Promise // initialTouched is only used for testing the error state of the form. diff --git a/site/src/pages/LoginPage/LoginPage.tsx b/site/src/pages/LoginPage/LoginPage.tsx index 924605db9f3bd..305012425130d 100644 --- a/site/src/pages/LoginPage/LoginPage.tsx +++ b/site/src/pages/LoginPage/LoginPage.tsx @@ -40,7 +40,7 @@ export const LoginPage: React.FC = () => { authSend({ type: "SIGN_IN", email, password }) } - const { authError, getUserError, checkPermissionsError, getMethodsError } = authState.context + const { authError, checkPermissionsError, getMethodsError } = authState.context if (authState.matches("signedIn")) { return @@ -58,7 +58,6 @@ export const LoginPage: React.FC = () => { isLoading={isLoading} loginErrors={{ authError, - getUserError, checkPermissionsError, getMethodsError, }} From 3dbd3f34c9b48e7ceee466bdd25352f057609f13 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 28 Jul 2022 21:06:31 +0000 Subject: [PATCH 5/5] use makeMockApiError helper --- .../SignInForm/SignInForm.stories.tsx | 35 +++++++------------ .../SSHKeysPage/SSHKeysPageView.stories.tsx | 23 ++++-------- 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/site/src/components/SignInForm/SignInForm.stories.tsx b/site/src/components/SignInForm/SignInForm.stories.tsx index b32449af64f55..1937dfd066a5b 100644 --- a/site/src/components/SignInForm/SignInForm.stories.tsx +++ b/site/src/components/SignInForm/SignInForm.stories.tsx @@ -1,4 +1,5 @@ import { Story } from "@storybook/react" +import { makeMockApiError } from "testHelpers/entities" import { LoginErrors, SignInForm, SignInFormProps } from "./SignInForm" export default { @@ -35,20 +36,15 @@ export const WithLoginError = Template.bind({}) WithLoginError.args = { ...SignedOut.args, loginErrors: { - [LoginErrors.AUTH_ERROR]: { - response: { - data: { - message: "Email or password was invalid", - validations: [ - { - field: "password", - detail: "Password is invalid.", - }, - ], + [LoginErrors.AUTH_ERROR]: makeMockApiError({ + message: "Email or password was invalid", + validations: [ + { + field: "password", + detail: "Password is invalid.", }, - }, - isAxiosError: true, - }, + ], + }), }, initialTouched: { password: true, @@ -59,15 +55,10 @@ export const WithCheckPermissionsError = Template.bind({}) WithCheckPermissionsError.args = { ...SignedOut.args, loginErrors: { - [LoginErrors.CHECK_PERMISSIONS_ERROR]: { - response: { - data: { - message: "Unable to fetch user permissions", - detail: "Resource not found or you do not have access to this resource.", - }, - }, - isAxiosError: true, - }, + [LoginErrors.CHECK_PERMISSIONS_ERROR]: makeMockApiError({ + message: "Unable to fetch user permissions", + detail: "Resource not found or you do not have access to this resource.", + }), }, } diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx index 7641580bb4d48..4342dba6b8237 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPageView.stories.tsx @@ -1,4 +1,5 @@ import { Story } from "@storybook/react" +import { makeMockApiError } from "testHelpers/entities" import { SSHKeysPageView, SSHKeysPageViewProps } from "./SSHKeysPageView" export default { @@ -38,25 +39,15 @@ export const WithGetSSHKeyError = Template.bind({}) WithGetSSHKeyError.args = { ...Example.args, hasLoaded: false, - getSSHKeyError: { - response: { - data: { - message: "Failed to get SSH key", - }, - }, - isAxiosError: true, - }, + getSSHKeyError: makeMockApiError({ + message: "Failed to get SSH key", + }), } export const WithRegenerateSSHKeyError = Template.bind({}) WithRegenerateSSHKeyError.args = { ...Example.args, - regenerateSSHKeyError: { - response: { - data: { - message: "Failed to regenerate SSH key", - }, - }, - isAxiosError: true, - }, + regenerateSSHKeyError: makeMockApiError({ + message: "Failed to regenerate SSH key", + }), } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy