mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
fix: show error when creating a new group fails (#11560)
This commit is contained in:
committed by
GitHub
parent
905292053a
commit
4c3f05b8aa
@ -48,7 +48,8 @@ func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request)
|
||||
|
||||
if req.Name == database.EveryoneGroup {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: fmt.Sprintf("%q is a reserved keyword and cannot be used for a group name.", database.EveryoneGroup),
|
||||
Message: "Invalid group name.",
|
||||
Validations: []codersdk.ValidationError{{Field: "name", Detail: fmt.Sprintf("%q is a reserved group name", req.Name)}},
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -63,7 +64,8 @@ func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request)
|
||||
})
|
||||
if database.IsUniqueViolation(err) {
|
||||
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
|
||||
Message: fmt.Sprintf("Group with name %q already exists.", req.Name),
|
||||
Message: fmt.Sprintf("A group named %q already exists.", req.Name),
|
||||
Validations: []codersdk.ValidationError{{Field: "name", Detail: "Group names must be unique"}},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export const CreateGroupPage: FC = () => {
|
||||
});
|
||||
navigate(`/groups/${newGroup.id}`);
|
||||
}}
|
||||
formErrors={createGroupMutation.error}
|
||||
error={createGroupMutation.error}
|
||||
isLoading={createGroupMutation.isLoading}
|
||||
/>
|
||||
</>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { mockApiError } from "testHelpers/entities";
|
||||
import { CreateGroupPageView } from "./CreateGroupPageView";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
@ -9,6 +10,14 @@ const meta: Meta<typeof CreateGroupPageView> = {
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof CreateGroupPageView>;
|
||||
|
||||
const Example: Story = {};
|
||||
export const Example: Story = {};
|
||||
|
||||
export { Example as CreateGroupPageView };
|
||||
export const WithError: Story = {
|
||||
args: {
|
||||
error: mockApiError({
|
||||
message: "A group named new-group already exists.",
|
||||
validations: [{ field: "name", detail: "Group names must be unique" }],
|
||||
}),
|
||||
initialTouched: { name: true },
|
||||
},
|
||||
};
|
||||
|
@ -1,15 +1,17 @@
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { CreateGroupRequest } from "api/typesGenerated";
|
||||
import { type FormikTouched, useFormik } from "formik";
|
||||
import { type FC } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import * as Yup from "yup";
|
||||
import type { CreateGroupRequest } from "api/typesGenerated";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { FormFooter } from "components/FormFooter/FormFooter";
|
||||
import { FullPageForm } from "components/FullPageForm/FullPageForm";
|
||||
import { IconField } from "components/IconField/IconField";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { useFormik } from "formik";
|
||||
import { FC } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { getFormHelpers, onChangeTrimmed } from "utils/formUtils";
|
||||
import * as Yup from "yup";
|
||||
import { isApiValidationError } from "api/errors";
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
name: Yup.string().required().label("Name"),
|
||||
@ -17,14 +19,17 @@ const validationSchema = Yup.object({
|
||||
|
||||
export type CreateGroupPageViewProps = {
|
||||
onSubmit: (data: CreateGroupRequest) => void;
|
||||
formErrors?: unknown;
|
||||
error?: unknown;
|
||||
isLoading: boolean;
|
||||
// Helpful to show field errors on Storybook
|
||||
initialTouched?: FormikTouched<CreateGroupRequest>;
|
||||
};
|
||||
|
||||
export const CreateGroupPageView: FC<CreateGroupPageViewProps> = ({
|
||||
onSubmit,
|
||||
formErrors,
|
||||
error,
|
||||
isLoading,
|
||||
initialTouched,
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const form = useFormik<CreateGroupRequest>({
|
||||
@ -36,8 +41,9 @@ export const CreateGroupPageView: FC<CreateGroupPageViewProps> = ({
|
||||
},
|
||||
validationSchema,
|
||||
onSubmit,
|
||||
initialTouched,
|
||||
});
|
||||
const getFieldHelpers = getFormHelpers<CreateGroupRequest>(form, formErrors);
|
||||
const getFieldHelpers = getFormHelpers<CreateGroupRequest>(form, error);
|
||||
const onCancel = () => navigate("/groups");
|
||||
|
||||
return (
|
||||
@ -45,6 +51,10 @@ export const CreateGroupPageView: FC<CreateGroupPageViewProps> = ({
|
||||
<FullPageForm title="Create group">
|
||||
<form onSubmit={form.handleSubmit}>
|
||||
<Stack spacing={2.5}>
|
||||
{Boolean(error) && !isApiValidationError(error) && (
|
||||
<ErrorAlert error={error} />
|
||||
)}
|
||||
|
||||
<TextField
|
||||
{...getFieldHelpers("name")}
|
||||
autoFocus
|
||||
|
@ -1946,7 +1946,7 @@ type MockAPIOutput = {
|
||||
};
|
||||
|
||||
export const mockApiError = ({
|
||||
message,
|
||||
message = "Something went wrong.",
|
||||
detail,
|
||||
validations,
|
||||
}: MockAPIInput): MockAPIOutput => ({
|
||||
@ -1954,9 +1954,9 @@ export const mockApiError = ({
|
||||
isAxiosError: true,
|
||||
response: {
|
||||
data: {
|
||||
message: message ?? "Something went wrong.",
|
||||
detail: detail ?? undefined,
|
||||
validations: validations ?? undefined,
|
||||
message,
|
||||
detail,
|
||||
validations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
Reference in New Issue
Block a user