import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { DialogFooter, DialogHeader } from "@/components/ui/dialog"; import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage, } from "@/components/ui/form"; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from "@/components/ui/select"; import { ToastAction } from "@/components/ui/toast"; import { DialogContent, DialogTitle } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { LoadingSpinner } from "@/components/ui/loading-spinner"; import { useToast } from "@/hooks/use-toast"; import { useTemplateImages } from "@/templates/api"; import { superstructResolver } from "@hookform/resolvers/superstruct"; import { useRef, useEffect } from "react"; import { useForm } from "react-hook-form"; import { nonempty, object, pattern, string, type Infer } from "superstruct"; import { useCreateWorkspace } from "./api"; interface NewWorkspaceDialogProps { onCreateSuccess: () => void; } const NewWorkspaceForm = object({ workspaceName: pattern(string(), /^[\w-]+$/), imageId: nonempty(string()), }); function NewWorkspaceDialog({ onCreateSuccess }: NewWorkspaceDialogProps) { const { data: templateImages, isLoading, error } = useTemplateImages(); const form = useForm({ resolver: superstructResolver(NewWorkspaceForm), defaultValues: { workspaceName: "", imageId: "", }, }); const { createWorkspace, status } = useCreateWorkspace(); const { toast } = useToast(); const formRef = useRef(null); useEffect(() => { switch (status.type) { case "error": toast({ variant: "destructive", title: "Failed to create the workspace.", action: ( { formRef.current?.requestSubmit(); }} altText="Try again" > Try again ), }); break; case "ok": onCreateSuccess(); break; default: break; } }, [status.type, toast, onCreateSuccess]); async function onSubmit(values: Infer) { await createWorkspace({ workspaceName: values.workspaceName, imageId: values.imageId, }); } function content() { if (error) { console.log(error); return (

An error occurred when fetching available options.

); } if (isLoading) { return (
); } if (!templateImages) { return null; } if (templateImages.length === 0) { return ( <>

No images found. Create and build a template, and the resulting image will show up here.

What are images? An image is used to bootstrap a workspace, including the operating system, the environment, and packages, as specified by a template. ); } return (
( Workspace name Must only contain alphanumeric characters and "-". )} /> ( Image for this workspace )} /> ); } return ( New workspace {content()} ); } export { NewWorkspaceDialog };