mirror of
https://github.com/coder/coder.git
synced 2026-09-22 13:10:21 +08:00
In v1, we had a quick and easy way to leave creation forms - an escape button (and key handler) in the top right corner. This was especially helpful in cases where the form was long enough that the 'Cancel' button was off-screen. This ports over that component into v2 and hooks up into our two existing forms: <img width="977" alt="Screen Shot 2022-02-09 at 5 48 03 PM" src="https://user-images.githubusercontent.com/88213859/153321503-af957f2b-d674-4ebf-9ac5-97939cb9153f.png"> In addition, this adds test cases + a storybook story for it.
100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import Button from "@material-ui/core/Button"
|
|
import { makeStyles } from "@material-ui/core/styles"
|
|
import { FormikContextType, useFormik } from "formik"
|
|
import React from "react"
|
|
import * as Yup from "yup"
|
|
|
|
import { FormCloseButton, FormTextField, FormTitle, FormSection } from "../components/Form"
|
|
import { LoadingButton } from "../components/Button"
|
|
import { Project, Workspace, CreateWorkspaceRequest } from "../api"
|
|
|
|
export interface CreateWorkspaceForm {
|
|
project: Project
|
|
onSubmit: (request: CreateWorkspaceRequest) => Promise<Workspace>
|
|
onCancel: () => void
|
|
}
|
|
|
|
const validationSchema = Yup.object({
|
|
name: Yup.string().required("Name is required"),
|
|
})
|
|
|
|
export const CreateWorkspaceForm: React.FC<CreateWorkspaceForm> = ({ project, onSubmit, onCancel }) => {
|
|
const styles = useStyles()
|
|
|
|
const form: FormikContextType<{ name: string }> = useFormik<{ name: string }>({
|
|
initialValues: {
|
|
name: "",
|
|
},
|
|
enableReinitialize: true,
|
|
validationSchema: validationSchema,
|
|
onSubmit: ({ name }) => {
|
|
return onSubmit({
|
|
project_id: project.id,
|
|
name: name,
|
|
})
|
|
},
|
|
})
|
|
|
|
return (
|
|
<div className={styles.root}>
|
|
<FormTitle
|
|
title="Create Workspace"
|
|
detail={
|
|
<span>
|
|
for project <strong>{project.name}</strong>
|
|
</span>
|
|
}
|
|
/>
|
|
<FormCloseButton onClose={onCancel} />
|
|
|
|
<FormSection title="Name">
|
|
<FormTextField
|
|
form={form}
|
|
formFieldName="name"
|
|
fullWidth
|
|
helperText="A unique name describing your workspace."
|
|
label="Workspace Name"
|
|
placeholder="my-workspace"
|
|
required
|
|
/>
|
|
</FormSection>
|
|
|
|
<div className={styles.footer}>
|
|
<Button className={styles.button} onClick={onCancel} variant="outlined">
|
|
Cancel
|
|
</Button>
|
|
<LoadingButton
|
|
loading={form.isSubmitting}
|
|
className={styles.button}
|
|
onClick={form.submitForm}
|
|
variant="contained"
|
|
color="primary"
|
|
type="submit"
|
|
>
|
|
Submit
|
|
</LoadingButton>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const useStyles = makeStyles(() => ({
|
|
root: {
|
|
maxWidth: "1380px",
|
|
width: "100%",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
},
|
|
footer: {
|
|
display: "flex",
|
|
flex: "0",
|
|
flexDirection: "row",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
button: {
|
|
margin: "1em",
|
|
},
|
|
}))
|