| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import { zodResolver } from '@hookform/resolvers/zod'
- import { parseAsBoolean, useQueryState } from 'nuqs'
- import { SubmitHandler, useForm } from 'react-hook-form'
- import { toast } from 'sonner'
- import {
- Button,
- Dialog,
- DialogContent,
- DialogFooter,
- DialogHeader,
- DialogSection,
- DialogSectionSeparator,
- DialogTitle,
- Form,
- FormControl,
- FormField,
- Input,
- } from 'ui'
- import { Input as PasswordInput } from 'ui-patterns/DataInputs/Input'
- import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
- import * as z from 'zod'
- import { useVaultSecretCreateMutation } from '@/data/vault/vault-secret-create-mutation'
- import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
- const formSchema = z.object({
- name: z.string().min(1, 'Please provide a name for your secret'),
- description: z.string().optional(),
- secret: z.string().min(1, 'Please enter your secret value'),
- })
- type FormSchema = z.infer<typeof formSchema>
- const formId = 'add-new-secret-form'
- export const AddNewSecretModal = () => {
- const { data: project } = useSelectedProjectQuery()
- const { mutateAsync: addSecret } = useVaultSecretCreateMutation()
- const [showAddSecretModal, setShowAddSecretModal] = useQueryState(
- 'new',
- parseAsBoolean.withDefault(false)
- )
- const handleClose = () => {
- setShowAddSecretModal(null)
- form.reset()
- }
- const onAddNewSecret: SubmitHandler<FormSchema> = async (values) => {
- if (!project) return console.error('Project is required')
- try {
- await addSecret({
- projectRef: project.ref,
- connectionString: project?.connectionString,
- name: values.name,
- description: values.description,
- secret: values.secret,
- })
- toast.success(`Successfully added new secret ${values.name}`)
- handleClose()
- } catch (error: any) {
- // [Joshen] No error handler required as they are all handled within the mutations already
- } finally {
- }
- }
- const form = useForm<FormSchema>({
- resolver: zodResolver(formSchema as any),
- defaultValues: { name: '', description: '', secret: '' },
- })
- const { isDirty, isSubmitting } = form.formState
- return (
- <Dialog open={showAddSecretModal} onOpenChange={handleClose}>
- <DialogContent className="sm:max-w-[425px]">
- <DialogHeader>
- <DialogTitle>Add new secret</DialogTitle>
- </DialogHeader>
- <DialogSectionSeparator />
- <DialogSection className="space-y-4">
- <Form {...form}>
- <form
- id={formId}
- noValidate
- onSubmit={form.handleSubmit(onAddNewSecret)}
- className="space-y-4"
- >
- <FormField
- control={form.control}
- name="name"
- render={({ field }) => (
- <FormItemLayout layout="vertical" label="Name">
- <FormControl className="col-span-6">
- <Input {...field} />
- </FormControl>
- </FormItemLayout>
- )}
- />
- <FormField
- control={form.control}
- name="description"
- render={({ field }) => (
- <FormItemLayout layout="vertical" label="Description" labelOptional="Optional">
- <FormControl className="col-span-6">
- <Input {...field} />
- </FormControl>
- </FormItemLayout>
- )}
- />
- <FormField
- control={form.control}
- name="secret"
- render={({ field }) => (
- <FormItemLayout layout="vertical" label="Secret value">
- <FormControl className="col-span-6">
- <PasswordInput reveal copy {...field} />
- </FormControl>
- </FormItemLayout>
- )}
- />
- </form>
- </Form>
- </DialogSection>
- <DialogFooter>
- <Button type="default" disabled={isSubmitting} onClick={handleClose}>
- Cancel
- </Button>
- <Button
- form={formId}
- htmlType="submit"
- disabled={!isDirty || isSubmitting}
- loading={isSubmitting}
- >
- Add secret
- </Button>
- </DialogFooter>
- </DialogContent>
- </Dialog>
- )
- }
|