diff --git a/apps/dokploy/components/dashboard/application/patches/edit-patch-dialog.tsx b/apps/dokploy/components/dashboard/application/patches/edit-patch-dialog.tsx new file mode 100644 index 000000000..284b62d10 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/patches/edit-patch-dialog.tsx @@ -0,0 +1,102 @@ +import { Loader2, Pencil } from "lucide-react"; +import { useEffect, useState } from "react"; +import { toast } from "sonner"; +import { CodeEditor } from "@/components/shared/code-editor"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { api } from "@/utils/api"; + +interface Props { + patchId: string; + entityId: string; + type: "application" | "compose"; + onSuccess?: () => void; +} + +export const EditPatchDialog = ({ + patchId, + entityId, + type, + onSuccess, +}: Props) => { + const { data: patch, isLoading: isPatchLoading } = api.patch.one.useQuery( + { patchId }, + { enabled: !!patchId }, + ); + const [content, setContent] = useState(""); + + useEffect(() => { + if (patch) { + setContent(patch.content); + } + }, [patch]); + + const utils = api.useUtils(); + const updatePatch = api.patch.update.useMutation(); + + const handleSave = () => { + updatePatch + .mutateAsync({ patchId, content }) + .then(() => { + toast.success("Patch saved"); + utils.patch.byEntityId.invalidate({ id: entityId, type }); + onSuccess?.(); + }) + .catch((err) => { + toast.error(err.message); + }); + }; + + return ( + + + + + + + Edit Patch + + {patch ? `Editing: ${patch.filePath}` : "Loading patch..."} + + + {isPatchLoading ? ( +
+ +
+ ) : ( +
+ setContent(value ?? "")} + className="h-[400px] w-full" + wrapperClassName="h-[400px]" + lineWrapping + /> +
+ )} + + + + + + +
+
+ ); +}; diff --git a/apps/dokploy/components/dashboard/application/patches/show-patches.tsx b/apps/dokploy/components/dashboard/application/patches/show-patches.tsx index 2a090e39f..eace7d820 100644 --- a/apps/dokploy/components/dashboard/application/patches/show-patches.tsx +++ b/apps/dokploy/components/dashboard/application/patches/show-patches.tsx @@ -19,6 +19,7 @@ import { TableRow, } from "@/components/ui/table"; import { api } from "@/utils/api"; +import { EditPatchDialog } from "./edit-patch-dialog"; import { PatchEditor } from "./patch-editor"; interface Props { @@ -82,7 +83,7 @@ export const ShowPatches = ({ id, type }: Props) => { return ( - +
Patches @@ -129,7 +130,7 @@ export const ShowPatches = ({ id, type }: Props) => { File Path Enabled - Actions + Actions @@ -167,25 +168,33 @@ export const ShowPatches = ({ id, type }: Props) => { /> - + }} + title="Delete patch" + > + + +
))} diff --git a/apps/dokploy/server/api/routers/patch.ts b/apps/dokploy/server/api/routers/patch.ts index 1c9eb4fe3..0279c8916 100644 --- a/apps/dokploy/server/api/routers/patch.ts +++ b/apps/dokploy/server/api/routers/patch.ts @@ -29,11 +29,9 @@ import { } from "@/server/db/schema"; export const patchRouter = createTRPCRouter({ - // CRUD Operations create: protectedProcedure .input(apiCreatePatch) .mutation(async ({ input, ctx }) => { - // Verify access if (input.applicationId) { const app = await findApplicationById(input.applicationId); if (