UpdateModal.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { zodResolver } from '@hookform/resolvers/zod'
  2. import { useParams } from 'common'
  3. import { useEffect } from 'react'
  4. import { SubmitHandler, useForm } from 'react-hook-form'
  5. import { toast } from 'sonner'
  6. import { Button, Form, FormControl, FormField, Input, Modal, Textarea } from 'ui'
  7. import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
  8. import * as z from 'zod'
  9. import { Content } from '@/data/content/content-query'
  10. import { useContentUpsertMutation } from '@/data/content/content-upsert-mutation'
  11. const formSchema = z.object({
  12. name: z.string().min(1, 'Required'),
  13. description: z.string().optional(),
  14. })
  15. type CustomReport = z.infer<typeof formSchema>
  16. export interface UpdateCustomReportProps {
  17. selectedReport?: Content
  18. initialValues: CustomReport
  19. onCancel: () => void
  20. }
  21. export const UpdateCustomReportModal = ({
  22. selectedReport,
  23. initialValues,
  24. onCancel,
  25. }: UpdateCustomReportProps) => {
  26. const { ref } = useParams()
  27. const { mutate: updateReport, isPending: isUpdating } = useContentUpsertMutation({
  28. onSuccess: () => {
  29. toast.success('Successfully updated report')
  30. onCancel()
  31. },
  32. onError: (error) => {
  33. toast.error(`Failed to update report: ${error.message}`)
  34. },
  35. })
  36. const onConfirmUpdateReport: SubmitHandler<CustomReport> = (newVals) => {
  37. if (!ref) return console.error('Project ref is required')
  38. if (!selectedReport) return
  39. if (!selectedReport.id) return
  40. if (!selectedReport.project_id) return
  41. updateReport({
  42. projectRef: ref,
  43. payload: {
  44. ...selectedReport,
  45. owner_id: selectedReport.owner_id!,
  46. project_id: selectedReport.project_id,
  47. id: selectedReport.id,
  48. name: newVals.name,
  49. description: newVals.description || '',
  50. },
  51. })
  52. }
  53. const handleCancel = () => {
  54. onCancel()
  55. form.reset()
  56. }
  57. const form = useForm<CustomReport>({
  58. resolver: zodResolver(formSchema as any),
  59. defaultValues: initialValues,
  60. })
  61. const { formState, reset } = form
  62. const { isDirty } = formState
  63. useEffect(() => {
  64. if (isDirty) return
  65. reset(initialValues)
  66. }, [initialValues, isDirty, reset])
  67. return (
  68. <Modal
  69. visible={selectedReport !== undefined}
  70. onCancel={handleCancel}
  71. hideFooter
  72. header="Update custom report"
  73. size="small"
  74. >
  75. <Form {...form}>
  76. <form onSubmit={form.handleSubmit(onConfirmUpdateReport)} noValidate>
  77. <Modal.Content>
  78. <FormField
  79. control={form.control}
  80. name="name"
  81. render={({ field }) => (
  82. <FormItemLayout name="name" layout="vertical" label="Name">
  83. <FormControl>
  84. <Input {...field} id="name" />
  85. </FormControl>
  86. </FormItemLayout>
  87. )}
  88. />
  89. </Modal.Content>
  90. <Modal.Content>
  91. <FormField
  92. control={form.control}
  93. name="description"
  94. render={({ field }) => (
  95. <FormItemLayout name="description" layout="vertical" label="Description">
  96. <FormControl>
  97. <Textarea
  98. {...field}
  99. id="description"
  100. rows={4}
  101. placeholder="Describe your custom report"
  102. className="resize-none"
  103. />
  104. </FormControl>
  105. </FormItemLayout>
  106. )}
  107. />
  108. </Modal.Content>
  109. <Modal.Separator />
  110. <Modal.Content className="flex items-center justify-end gap-2">
  111. <Button htmlType="reset" type="default" onClick={handleCancel} disabled={isUpdating}>
  112. Cancel
  113. </Button>
  114. <Button htmlType="submit" loading={isUpdating} disabled={isUpdating || !isDirty}>
  115. Save custom report
  116. </Button>
  117. </Modal.Content>
  118. </form>
  119. </Form>
  120. </Modal>
  121. )
  122. }