refactor: Update create workspace flow to allow creation from the workspaces page (#1684)

This commit is contained in:
Bruno Quaresma
2022-05-24 08:37:44 -05:00
committed by GitHub
parent 5f8d0e5dad
commit fcd610ee7b
11 changed files with 368 additions and 262 deletions

View File

@ -1,16 +1,19 @@
import { makeStyles } from "@material-ui/core/styles"
import TextField from "@material-ui/core/TextField"
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 -",
@ -24,12 +27,15 @@ const maxLenName = 32
const usernameRE = /^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$/
export interface CreateWorkspacePageViewProps {
loading?: boolean
template: TypesGen.Template
templateSchema: TypesGen.ParameterSchema[]
loadingTemplates: boolean
loadingTemplateSchema: boolean
creatingWorkspace: boolean
templates?: TypesGen.Template[]
selectedTemplate?: TypesGen.Template
templateSchema?: TypesGen.ParameterSchema[]
onCancel: () => void
onSubmit: (req: TypesGen.CreateWorkspaceRequest) => Promise<void>
onSubmit: (req: TypesGen.CreateWorkspaceRequest) => void
onSelectTemplate: (template: TypesGen.Template) => void
}
export const validationSchema = Yup.object({
@ -40,15 +46,19 @@ export const validationSchema = Yup.object({
})
export const CreateWorkspacePageView: React.FC<CreateWorkspacePageViewProps> = (props) => {
const styles = useStyles()
const [parameterValues, setParameterValues] = React.useState<Record<string, string>>({})
const form: FormikContextType<TypesGen.CreateWorkspaceRequest> = useFormik<TypesGen.CreateWorkspaceRequest>({
initialValues: {
name: "",
template_id: props.template.id,
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
@ -70,49 +80,84 @@ export const CreateWorkspacePageView: React.FC<CreateWorkspacePageViewProps> = (
})
const getFieldHelpers = getFormHelpers<TypesGen.CreateWorkspaceRequest>(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 (
<Margins>
<FullPageForm title="Create workspace" onCancel={props.onCancel}>
<form onSubmit={form.handleSubmit}>
<TextField
{...getFieldHelpers("name")}
disabled={form.isSubmitting}
onChange={onChangeTrimmed(form)}
autoFocus
fullWidth
label={Language.nameLabel}
variant="outlined"
/>
{props.templateSchema.length > 0 && (
<div className={styles.parameters}>
{props.templateSchema.map((schema) => (
<ParameterInput
disabled={form.isSubmitting}
key={schema.id}
onChange={(value) => {
setParameterValues({
...parameterValues,
[schema.name]: value,
})
}}
schema={schema}
/>
))}
</div>
)}
{props.loadingTemplates && <Loader />}
<FormFooter onCancel={props.onCancel} isLoading={props.loading || form.isSubmitting} />
<Stack>
{props.templates && (
<TextField
{...getFieldHelpers("template_id")}
disabled={form.isSubmitting}
onChange={handleTemplateChange}
autoFocus
fullWidth
label={Language.templateLabel}
variant="outlined"
select
>
{props.templates.map((template) => (
<MenuItem key={template.id} value={template.id}>
{template.name}
</MenuItem>
))}
</TextField>
)}
{props.selectedTemplate && props.templateSchema && (
<>
<TextField
{...getFieldHelpers("name")}
disabled={form.isSubmitting}
onChange={onChangeTrimmed(form)}
autoFocus
fullWidth
label={Language.nameLabel}
variant="outlined"
/>
{props.templateSchema.length > 0 && (
<Stack>
{props.templateSchema.map((schema) => (
<ParameterInput
disabled={form.isSubmitting}
key={schema.id}
onChange={(value) => {
setParameterValues({
...parameterValues,
[schema.name]: value,
})
}}
schema={schema}
/>
))}
</Stack>
)}
<FormFooter onCancel={props.onCancel} isLoading={props.creatingWorkspace} />
</>
)}
</Stack>
</form>
</FullPageForm>
</Margins>
)
}
const useStyles = makeStyles((theme) => ({
parameters: {
paddingTop: theme.spacing(4),
"& > *": {
marginBottom: theme.spacing(4),
},
},
}))