import Link from "@mui/material/Link"; import MenuItem from "@mui/material/MenuItem"; import TextField from "@mui/material/TextField"; import { hasApiFieldErrors, isApiError } from "api/errors"; import type * as TypesGen from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Button } from "components/Button/Button"; import { FormFooter } from "components/Form/Form"; import { FullPageForm } from "components/FullPageForm/FullPageForm"; import { PasswordField } from "components/PasswordField/PasswordField"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; import { type FormikContextType, useFormik } from "formik"; import type { FC } from "react"; import { displayNameValidator, getFormHelpers, nameValidator, onChangeTrimmed, } from "utils/formUtils"; import * as Yup from "yup"; export const Language = { emailLabel: "Email", passwordLabel: "Password", usernameLabel: "Username", nameLabel: "Full name", emailInvalid: "Please enter a valid email address.", emailRequired: "Please enter an email address.", passwordRequired: "Please enter a password.", createUser: "Create", cancel: "Cancel", }; export const authMethodLanguage = { password: { displayName: "Password", description: "Use an email address and password to login", }, oidc: { displayName: "OpenID Connect", description: "Use an OpenID Connect provider for authentication", }, github: { displayName: "Github", description: "Use Github OAuth for authentication", }, none: { displayName: "None", description: ( <> Disable authentication for this user (See the{" "} documentation {" "} for more details) ), }, }; export interface CreateUserFormProps { onSubmit: (user: TypesGen.CreateUserRequestWithOrgs) => void; onCancel: () => void; error?: unknown; isLoading: boolean; authMethods?: TypesGen.AuthMethods; } const validationSchema = Yup.object({ email: Yup.string() .trim() .email(Language.emailInvalid) .required(Language.emailRequired), password: Yup.string().when("login_type", { is: "password", then: (schema) => schema.required(Language.passwordRequired), otherwise: (schema) => schema, }), username: nameValidator(Language.usernameLabel), name: displayNameValidator(Language.nameLabel), login_type: Yup.string().oneOf(Object.keys(authMethodLanguage)), }); export const CreateUserForm: FC< React.PropsWithChildren > = ({ onSubmit, onCancel, error, isLoading, authMethods }) => { const form: FormikContextType = useFormik({ initialValues: { email: "", password: "", username: "", name: "", organization_ids: ["00000000-0000-0000-0000-000000000000"], login_type: "", user_status: null, }, validationSchema, onSubmit, }); const getFieldHelpers = getFormHelpers( form, error, ); const methods = [ authMethods?.password.enabled && "password", authMethods?.oidc.enabled && "oidc", authMethods?.github.enabled && "github", "none", ].filter(Boolean) as Array; return ( {isApiError(error) && !hasApiFieldErrors(error) && ( )}
{ if (e.target.value !== "password") { await form.setFieldValue("password", ""); } await form.setFieldValue("login_type", e.target.value); }} SelectProps={{ renderValue: (selected: unknown) => authMethodLanguage[selected as keyof typeof authMethodLanguage] ?.displayName ?? "", }} > {methods.map((value) => { const language = authMethodLanguage[value]; return ( {language.displayName} ({ fontSize: 14, color: theme.palette.text.secondary, wordWrap: "normal", whiteSpace: "break-spaces", })} > {language.description} ); })}
); };