SchemaEditor.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { zodResolver } from '@hookform/resolvers/zod'
  2. import { useEffect } from 'react'
  3. import { SubmitHandler, useForm } from 'react-hook-form'
  4. import { toast } from 'sonner'
  5. import {
  6. Button,
  7. Dialog,
  8. DialogContent,
  9. DialogFooter,
  10. DialogHeader,
  11. DialogSection,
  12. DialogSectionSeparator,
  13. DialogTitle,
  14. Form,
  15. FormControl,
  16. FormField,
  17. Input,
  18. } from 'ui'
  19. import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
  20. import * as z from 'zod'
  21. import { useSchemaCreateMutation } from '@/data/database/schema-create-mutation'
  22. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  23. interface SchemaEditorProps {
  24. visible: boolean
  25. onSuccess: (schema: string) => void
  26. closePanel: () => void
  27. }
  28. const formSchema = z.object({
  29. name: z.string().min(1, 'Please provide a name for your schema'),
  30. })
  31. type FormSchema = z.infer<typeof formSchema>
  32. export const SchemaEditor = ({ visible, onSuccess, closePanel }: SchemaEditorProps) => {
  33. const { data: project } = useSelectedProjectQuery()
  34. const { mutateAsync: createSchema, isPending } = useSchemaCreateMutation()
  35. const onSubmit: SubmitHandler<FormSchema> = async (values) => {
  36. if (project === undefined) return console.error('Project is required')
  37. try {
  38. await createSchema({
  39. projectRef: project.ref,
  40. connectionString: project.connectionString,
  41. name: values.name,
  42. })
  43. onSuccess(values.name)
  44. toast.success(`Successfully created schema "${values.name}"`)
  45. } catch (error) {
  46. toast.error(`Failed to create schema: ${error}`)
  47. }
  48. }
  49. const form = useForm<FormSchema>({
  50. resolver: zodResolver(formSchema as any),
  51. defaultValues: {
  52. name: '',
  53. },
  54. })
  55. const { reset } = form
  56. useEffect(() => {
  57. if (visible) {
  58. reset()
  59. }
  60. }, [reset, visible])
  61. const formId = 'schema-form'
  62. return (
  63. <Dialog open={visible} onOpenChange={closePanel}>
  64. <DialogContent className="sm:max-w-[425px]">
  65. <DialogHeader>
  66. <DialogTitle>Create a new schema</DialogTitle>
  67. </DialogHeader>
  68. <DialogSectionSeparator />
  69. <DialogSection>
  70. <Form {...form}>
  71. <form id={formId} onSubmit={form.handleSubmit(onSubmit)} className="grow px-0">
  72. <FormField
  73. control={form.control}
  74. name="name"
  75. render={({ field }) => (
  76. <FormItemLayout layout="vertical" label="Schema name">
  77. <FormControl>
  78. <Input {...field} />
  79. </FormControl>
  80. </FormItemLayout>
  81. )}
  82. />
  83. </form>
  84. </Form>
  85. </DialogSection>
  86. <DialogFooter>
  87. <Button
  88. type="default"
  89. onClick={() => {
  90. form.reset()
  91. closePanel()
  92. }}
  93. disabled={isPending}
  94. >
  95. Cancel
  96. </Button>
  97. <Button
  98. type="primary"
  99. form={formId}
  100. htmlType="submit"
  101. loading={isPending}
  102. disabled={isPending}
  103. >
  104. Save
  105. </Button>
  106. </DialogFooter>
  107. </DialogContent>
  108. </Dialog>
  109. )
  110. }