Move error type predicate to xservice

This commit is contained in:
Presley
2022-04-27 02:43:33 +00:00
parent 6a490c2ee6
commit 7d98c13175
2 changed files with 26 additions and 12 deletions

View File

@ -1,7 +1,6 @@
import { useActor } from "@xstate/react"
import React, { useContext } from "react"
import { useNavigate } from "react-router"
import { isApiError, mapApiErrorToFieldErrors } from "../../../api/errors"
import { CreateUserRequest } from "../../../api/typesGenerated"
import { CreateUserForm } from "../../../components/CreateUserForm/CreateUserForm"
import { XServiceContext } from "../../../xServices/StateContext"
@ -13,19 +12,18 @@ export const Language = {
export const CreateUserPage = () => {
const xServices = useContext(XServiceContext)
const [usersState, usersSend] = useActor(xServices.usersXService)
const { createUserError } = usersState.context
const apiError = isApiError(createUserError)
const formErrors = apiError ? mapApiErrorToFieldErrors(createUserError.response.data) : undefined
const hasUnknownError = createUserError && !apiError
const { createUserError, createUserFormErrors } = usersState.context
const navigate = useNavigate()
// There is no field for organization id in Community Edition, so handle its field error like a generic error
const genericError = (createUserError || createUserFormErrors?.organization_id) ? Language.unknownError : undefined
return (
<CreateUserForm
formErrors={formErrors}
formErrors={createUserFormErrors}
onSubmit={(user: CreateUserRequest) => usersSend({ type: "CREATE", user })}
onCancel={() => navigate("/users")}
isLoading={usersState.hasTag("loading")}
error={hasUnknownError ? Language.unknownError : undefined}
error={genericError}
/>
)
}

View File

@ -1,6 +1,7 @@
import { NavigateFunction } from "react-router"
import { assign, createMachine } from "xstate"
import * as API from "../../api"
import { ApiError, FieldErrors, isApiError, mapApiErrorToFieldErrors } from "../../api/errors"
import * as Types from "../../api/types"
import * as TypesGen from "../../api/typesGenerated"
import { displaySuccess } from "../../components/GlobalSnackbar/utils"
@ -14,6 +15,7 @@ export interface UsersContext {
pager?: Types.Pager
getUsersError?: Error | unknown
createUserError?: Error | unknown
createUserFormErrors?: FieldErrors
navigate?: NavigateFunction
}
@ -73,10 +75,17 @@ export const usersMachine = createMachine(
target: "idle",
actions: ["displayCreateUserSuccess", "redirectToUsersPage", "clearCreateUserError"],
},
onError: {
target: "idle",
actions: ["assignCreateUserError"],
},
onError: [
{
target: "idle",
cond: "isFormError",
actions: ["assignCreateUserFormErrors"],
},
{
target: "idle",
actions: ["assignCreateUserError"],
},
],
},
tags: "loading",
},
@ -92,6 +101,9 @@ export const usersMachine = createMachine(
getUsers: API.getUsers,
createUser: (_, event) => API.createUser(event.user),
},
guards: {
isFormError: (_, event) => isApiError(event.data)
},
actions: {
assignUsers: assign({
users: (_, event) => event.data.page,
@ -107,6 +119,10 @@ export const usersMachine = createMachine(
assignCreateUserError: assign({
createUserError: (_, event) => event.data,
}),
assignCreateUserFormErrors: assign({
// the guard ensures it is ApiError
createUserFormErrors: (_, event) => mapApiErrorToFieldErrors((event.data as ApiError).response.data)
}),
clearCreateUserError: assign((context: UsersContext) => ({
...context,
createUserError: undefined,
@ -116,7 +132,7 @@ export const usersMachine = createMachine(
},
redirectToUsersPage: (context) => {
context.navigate && context.navigate("/users")
}
},
},
},
)