import { useRouter } from "next/router"; import { Button } from "@/src/components/ui/button"; import { api } from "@/src/utils/api"; import { Copy } from "lucide-react"; import { useHasProjectAccess } from "@/src/features/rbac/utils/checkProjectAccess"; import { Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/src/components/ui/dialog"; import { ActionButton } from "@/src/components/ActionButton"; import { usePostHogClientCapture } from "@/src/features/posthog-analytics/usePostHogClientCapture"; import { useEntitlementLimit } from "@/src/features/entitlements/hooks"; import { useState } from "react"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/src/components/ui/form"; import { useForm } from "react-hook-form"; import { z } from "zod/v4"; import { zodResolver } from "@hookform/resolvers/zod"; import { Input } from "@/src/components/ui/input"; import { RadioGroup, RadioGroupItem } from "@/src/components/ui/radio-group"; import { usePromptNameValidation } from "@/src/features/prompts/hooks/usePromptNameValidation"; enum CopySettings { SINGLE_VERSION = "single_version", ALL_VERSIONS = "all_versions", } const formSchema = z.object({ name: z.string().min(1, "Name is required"), isCopySingleVersion: z.enum(CopySettings), }); const DuplicatePromptForm: React.FC<{ projectId: string; promptId: string; promptName: string; promptVersion: number; onFormSuccess: () => void; }> = ({ projectId, promptId, promptName, promptVersion, onFormSuccess }) => { const capture = usePostHogClientCapture(); const router = useRouter(); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { name: promptName + "-copy", isCopySingleVersion: CopySettings.SINGLE_VERSION, }, }); const currentName = form.watch("name"); const utils = api.useUtils(); const duplicatePrompt = api.prompts.duplicatePrompt.useMutation({ onSuccess: ({ name }) => { utils.prompts.invalidate(); void router.push( `/project/${projectId}/prompts/${encodeURIComponent(name)}`, ); }, }); function onSubmit(values: z.infer) { capture("prompt_detail:duplicate_form_submit"); duplicatePrompt .mutateAsync({ ...values, projectId: projectId, promptId: promptId, isSingleVersion: values.isCopySingleVersion === CopySettings.SINGLE_VERSION, }) .then(() => { onFormSuccess(); form.reset(); }) .catch((error: Error) => { console.error(error); }); } const allPrompts = api.prompts.filterOptions.useQuery( { projectId: projectId, }, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, staleTime: Infinity, }, ).data?.name; usePromptNameValidation({ currentName, allPrompts, form, }); return (
( Name )} /> ( Settings Copy only version {promptVersion} Copy all prompt versions and labels )} />
); }; export const DuplicatePromptButton: React.FC<{ projectId: string; promptId: string; promptName: string; promptVersion: number; }> = ({ projectId, promptId, promptName, promptVersion }) => { const [open, setOpen] = useState(false); const hasAccess = useHasProjectAccess({ projectId, scope: "prompts:CUD", }); const promptLimit = useEntitlementLimit("prompt-management-count-prompts"); const capture = usePostHogClientCapture(); const allPromptNames = api.prompts.allNames.useQuery( { projectId, }, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, enabled: hasAccess, }, ); return ( Duplicate prompt setOpen(false)} /> ); };