import { zodResolver } from '@hookform/resolvers/zod' import { Eye, EyeOff } from 'lucide-react' import { parseAsString, useQueryState } from 'nuqs' import { useEffect, useState } from 'react' import { useForm, type SubmitHandler } from 'react-hook-form' import { toast } from 'sonner' import { Button, Dialog, DialogContent, DialogFooter, DialogHeader, DialogSection, DialogSectionSeparator, DialogTitle, Form, FormControl, FormField, Input, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { z } from 'zod' import { useVaultSecretDecryptedValueQuery } from '@/data/vault/vault-secret-decrypted-value-query' import { useVaultSecretUpdateMutation } from '@/data/vault/vault-secret-update-mutation' import { useVaultSecretsQuery } from '@/data/vault/vault-secrets-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import type { VaultSecret } from '@/types' const SecretSchema = 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'), }) const formId = 'edit-vault-secret-form' export const EditSecretModal = () => { const { data: project } = useSelectedProjectQuery() const { data: secrets = [], isSuccess } = useVaultSecretsQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) const [secretIdToEdit, setSelectedSecretToEdit] = useQueryState('edit', parseAsString) const secret = secrets.find((secret) => secret.id === secretIdToEdit) const [showSecretValue, setShowSecretValue] = useState(false) const { data, isPending: isLoadingSecretValue } = useVaultSecretDecryptedValueQuery( { projectRef: project?.ref, id: secret?.id, connectionString: project?.connectionString, }, { enabled: !!project?.ref } ) const values = { name: secret?.name ?? '', description: secret?.description ?? '', secret: secret?.decryptedSecret ?? data ?? '', } const form = useForm>({ resolver: zodResolver(SecretSchema as any), defaultValues: values, values, }) const { mutate: updateSecret, isPending: isSubmitting } = useVaultSecretUpdateMutation() const onSubmit: SubmitHandler> = async (values) => { if (!project) return console.error('Project is required') if (!secret) return console.error('Secret is required') const payload: Partial = { secret: values.secret, } if (values.name !== secret.name) payload.name = values.name if (values.description !== secret.description) payload.description = values.description if (Object.keys(payload).length > 0) { updateSecret( { projectRef: project.ref, connectionString: project?.connectionString, id: secret.id, ...payload, }, { onSuccess: () => { toast.success('Successfully updated secret') setSelectedSecretToEdit(null) }, onError: (error) => { toast.error(`Failed to update secret: ${error.message}`) }, } ) } } useEffect(() => { if (isSuccess && !!secretIdToEdit && !secret) { toast('Secret not found') setSelectedSecretToEdit(null) } }, [isSuccess, secretIdToEdit, secret, setSelectedSecretToEdit]) return ( { if (!open) { form.reset() setSelectedSecretToEdit(null) } }} > Edit secret {isLoadingSecretValue ? ( ) : ( <>
( )} /> ( )} /> (
)} />
)}
) }