import { useQueryClient } from "@tanstack/react-query"; import React from "react"; import { useTranslation } from "react-i18next"; import { useCreateSecret } from "#/hooks/mutation/use-create-secret"; import { useUpdateSecret } from "#/hooks/mutation/use-update-secret"; import { SettingsInput } from "../settings-input"; import { cn } from "#/utils/utils"; import { BrandButton } from "../brand-button"; import { useGetSecrets } from "#/hooks/query/use-get-secrets"; import { GetSecretsResponse } from "#/api/secrets-service.types"; import { OptionalTag } from "../optional-tag"; interface SecretFormProps { mode: "add" | "edit"; selectedSecret: string | null; onCancel: () => void; } export function SecretForm({ mode, selectedSecret, onCancel, }: SecretFormProps) { const queryClient = useQueryClient(); const { t } = useTranslation(); const { data: secrets } = useGetSecrets(); const { mutate: createSecret } = useCreateSecret(); const { mutate: updateSecret } = useUpdateSecret(); const [error, setError] = React.useState(null); const secretDescription = (mode === "edit" && selectedSecret && secrets ?.find((secret) => secret.name === selectedSecret) ?.description?.trim()) || ""; const handleCreateSecret = ( name: string, value: string, description?: string, ) => { createSecret( { name, value, description }, { onSettled: onCancel, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["secrets"] }); }, }, ); }; const updateSecretOptimistically = ( oldName: string, name: string, description?: string, ) => { queryClient.setQueryData( ["secrets"], (oldSecrets) => { if (!oldSecrets) return []; return oldSecrets.map((secret) => { if (secret.name === oldName) { return { ...secret, name, description, }; } return secret; }); }, ); }; const revertOptimisticUpdate = () => { queryClient.invalidateQueries({ queryKey: ["secrets"] }); }; const handleEditSecret = ( secretToEdit: string, name: string, description?: string, ) => { updateSecretOptimistically(secretToEdit, name, description); updateSecret( { secretToEdit, name, description }, { onSettled: onCancel, onError: revertOptimisticUpdate, }, ); }; const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); const formData = new FormData(event.currentTarget); const name = formData.get("secret-name")?.toString(); const value = formData.get("secret-value")?.toString().trim(); const description = formData.get("secret-description")?.toString(); if (name) { setError(null); const isNameAlreadyUsed = secrets?.some( (secret) => secret.name === name && secret.name !== selectedSecret, ); if (isNameAlreadyUsed) { setError("Secret already exists"); return; } if (mode === "add") { if (!value) { setError(t("SECRETS$SECRET_VALUE_REQUIRED")); return; } handleCreateSecret(name, value, description || undefined); } else if (mode === "edit" && selectedSecret) { handleEditSecret(selectedSecret, name, description || undefined); } } }; const formTestId = mode === "add" ? "add-secret-form" : "edit-secret-form"; return (
{error &&

{error}

} {mode === "add" && (