import type { ServiceType } from "@dokploy/server/db/schema"; import { zodResolver } from "@hookform/resolvers/zod"; import copy from "copy-to-clipboard"; import { Copy, Trash2 } from "lucide-react"; import { useRouter } from "next/router"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; const deleteComposeSchema = z.object({ projectName: z.string().min(1, { message: "Compose name is required", }), deleteVolumes: z.boolean(), }); type DeleteCompose = z.infer; interface Props { id: string; type: ServiceType | "application"; } export const DeleteService = ({ id, type }: Props) => { const [isOpen, setIsOpen] = useState(false); const queryMap = { postgres: () => api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), mariadb: () => api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), application: () => api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), compose: () => api.compose.one.useQuery({ composeId: id }, { enabled: !!id }), }; const { data } = queryMap[type] ? queryMap[type]() : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); const mutationMap = { postgres: () => api.postgres.remove.useMutation(), redis: () => api.redis.remove.useMutation(), mysql: () => api.mysql.remove.useMutation(), mariadb: () => api.mariadb.remove.useMutation(), application: () => api.application.delete.useMutation(), mongo: () => api.mongo.remove.useMutation(), compose: () => api.compose.delete.useMutation(), }; const { mutateAsync, isLoading } = mutationMap[type] ? mutationMap[type]() : api.mongo.remove.useMutation(); const { push } = useRouter(); const form = useForm({ defaultValues: { projectName: "", deleteVolumes: false, }, resolver: zodResolver(deleteComposeSchema), }); const onSubmit = async (formData: DeleteCompose) => { const expectedName = `${data?.name}/${data?.appName}`; if (formData.projectName === expectedName) { const { deleteVolumes } = formData; await mutateAsync({ mongoId: id || "", postgresId: id || "", redisId: id || "", mysqlId: id || "", mariadbId: id || "", applicationId: id || "", composeId: id || "", deleteVolumes, }) .then((result) => { push( `/dashboard/project/${result?.environment?.projectId}/environment/${result?.environment?.environmentId}`, ); toast.success("Service deleted successfully"); setIsOpen(false); }) .catch(() => { toast.error("Error deleting the service"); }); } else { form.setError("projectName", { message: `Project name must match "${expectedName}"`, }); } }; const isDisabled = (data && "applicationStatus" in data && data?.applicationStatus === "running") || (data && "composeStatus" in data && data?.composeStatus === "running"); return ( Are you absolutely sure? This action cannot be undone. This will permanently delete the service. If you are sure please enter the service name to delete this service.
( To confirm, type{" "} { if (data?.name && data?.appName) { copy(`${data.name}/${data.appName}`); toast.success("Copied to clipboard. Be careful!"); } }} > {data?.name}/{data?.appName}  {" "} in the box below: )} /> {type === "compose" && ( (
Delete volumes associated with this compose
)} /> )}
{isDisabled && ( Cannot delete the service while it is running. Please wait for the build to finish and then try again. )}
); };