import MenuItem from "@material-ui/core/MenuItem" import TextField, { TextFieldProps } from "@material-ui/core/TextField" import { FormikContextType, useFormik } from "formik" import React from "react" import * as Yup from "yup" import * as TypesGen from "../../api/typesGenerated" import { FormFooter } from "../../components/FormFooter/FormFooter" import { FullPageForm } from "../../components/FullPageForm/FullPageForm" import { Loader } from "../../components/Loader/Loader" import { Margins } from "../../components/Margins/Margins" import { ParameterInput } from "../../components/ParameterInput/ParameterInput" import { Stack } from "../../components/Stack/Stack" import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils" export const Language = { templateLabel: "Template", nameLabel: "Name", nameRequired: "Please enter a name.", nameMatches: "Name must start with a-Z or 0-9 and can contain a-Z, 0-9 or -", nameMax: "Name cannot be longer than 32 characters", } // REMARK: Keep in sync with coderd/httpapi/httpapi.go#L40 const maxLenName = 32 // REMARK: Keep in sync with coderd/httpapi/httpapi.go#L18 const usernameRE = /^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$/ export interface CreateWorkspacePageViewProps { loadingTemplates: boolean loadingTemplateSchema: boolean creatingWorkspace: boolean templates?: TypesGen.Template[] selectedTemplate?: TypesGen.Template templateSchema?: TypesGen.ParameterSchema[] onCancel: () => void onSubmit: (req: TypesGen.CreateWorkspaceRequest) => void onSelectTemplate: (template: TypesGen.Template) => void } export const validationSchema = Yup.object({ name: Yup.string() .required(Language.nameRequired) .matches(usernameRE, Language.nameMatches) .max(maxLenName, Language.nameMax), }) export const CreateWorkspacePageView: React.FC = (props) => { const [parameterValues, setParameterValues] = React.useState>({}) const form: FormikContextType = useFormik({ initialValues: { name: "", template_id: props.selectedTemplate ? props.selectedTemplate.id : "", }, enableReinitialize: true, validationSchema, onSubmit: (request) => { if (!props.templateSchema) { throw new Error("No template schema loaded") } const createRequests: TypesGen.CreateParameterRequest[] = [] props.templateSchema.forEach((schema) => { let value = schema.default_source_value if (schema.name in parameterValues) { value = parameterValues[schema.name] } createRequests.push({ name: schema.name, destination_scheme: schema.default_destination_scheme, source_scheme: schema.default_source_scheme, source_value: value, }) }) return props.onSubmit({ ...request, parameter_values: createRequests, }) }, }) const getFieldHelpers = getFormHelpers(form) const handleTemplateChange: TextFieldProps["onChange"] = (event) => { if (!props.templates) { throw new Error("Templates are not loaded") } const templateId = event.target.value const selectedTemplate = props.templates.find((template) => template.id === templateId) if (!selectedTemplate) { throw new Error(`Template ${templateId} not found`) } form.setFieldValue("template_id", selectedTemplate.id) props.onSelectTemplate(selectedTemplate) } return (
{props.loadingTemplates && } {props.templates && ( {props.templates.map((template) => ( {template.name} ))} )} {props.selectedTemplate && props.templateSchema && ( <> {props.templateSchema.length > 0 && ( {props.templateSchema.map((schema) => ( { setParameterValues({ ...parameterValues, [schema.name]: value, }) }} schema={schema} /> ))} )} )}
) }