diff --git a/apps/dokploy/components/dashboard/application/patches/patch-editor.tsx b/apps/dokploy/components/dashboard/application/patches/patch-editor.tsx index 6092b9b85..6688896fe 100644 --- a/apps/dokploy/components/dashboard/application/patches/patch-editor.tsx +++ b/apps/dokploy/components/dashboard/application/patches/patch-editor.tsx @@ -41,7 +41,6 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => { const [expandedFolders, setExpandedFolders] = useState>( new Set(), ); - const [isSaving, setIsSaving] = useState(false); const { data: directories, isLoading: isDirLoading } = api.patch.readRepoDirectories.useQuery( @@ -49,27 +48,13 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => { { enabled: !!repoPath }, ); - const saveAsPatch = api.patch.saveFileAsPatch.useMutation({ - onSuccess: (result) => { - setIsSaving(false); - if (result.deleted) { - toast.success("No changes - patch removed"); - } else { - toast.success("Patch saved"); - } - setOriginalContent(fileContent); - }, - onError: () => { - setIsSaving(false); - toast.error("Failed to save patch"); - }, - }); + const { mutateAsync: saveAsPatch, isLoading: isSavingPatch } = + api.patch.saveFileAsPatch.useMutation(); - // Read file content when selected const { data: fileData, isFetching: isFileLoading } = api.patch.readRepoFile.useQuery( { - id: id || "", + id, type, repoPath, filePath: selectedFile || "", @@ -77,8 +62,6 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => { { enabled: !!selectedFile, onSuccess: (data) => { - setFileContent(data.content); - setOriginalContent(data.content); if (data.patchError) { toast.error(data.patchErrorMessage || "Failed to apply patch"); } @@ -104,14 +87,19 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => { const handleSave = () => { if (!selectedFile) return; - setIsSaving(true); - saveAsPatch.mutate({ + saveAsPatch({ id, type, repoPath, filePath: selectedFile, content: fileContent, - }); + }) + .then(() => { + toast.success("Patch saved"); + }) + .catch(() => { + toast.error("Failed to save patch"); + }); }; const hasChanges = fileContent !== originalContent; @@ -192,8 +180,8 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => { {selectedFile && ( - @@ -201,7 +189,6 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => {
- {/* File Tree */}
@@ -219,7 +206,6 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => {
- {/* Editor */}
{isFileLoading ? (
@@ -227,7 +213,7 @@ export const PatchEditor = ({ id, type, repoPath, onClose }: Props) => {
) : selectedFile ? ( setFileContent(value || "")} className="h-full w-full" wrapperClassName="h-full" diff --git a/apps/dokploy/server/api/routers/patch.ts b/apps/dokploy/server/api/routers/patch.ts index 9deae22e4..43486038e 100644 --- a/apps/dokploy/server/api/routers/patch.ts +++ b/apps/dokploy/server/api/routers/patch.ts @@ -51,8 +51,8 @@ const getApplicationGitConfig = ( }; case "gitea": return { - gitUrl: app.gitea?.gitUrl - ? `${app.gitea.gitUrl}/${app.giteaOwner}/${app.giteaRepository}.git` + gitUrl: app.gitea?.giteaUrl + ? `${app.gitea.giteaUrl}/${app.giteaOwner}/${app.giteaRepository}.git` : "", gitBranch: app.giteaBranch || "main", sshKeyId: null, @@ -93,8 +93,8 @@ const getComposeGitConfig = ( }; case "gitea": return { - gitUrl: compose.gitea?.gitUrl - ? `${compose.gitea.gitUrl}/${compose.giteaOwner}/${compose.giteaRepository}.git` + gitUrl: compose.gitea?.giteaUrl + ? `${compose.gitea.giteaUrl}/${compose.giteaOwner}/${compose.giteaRepository}.git` : "", gitBranch: compose.giteaBranch || "main", sshKeyId: null, @@ -343,7 +343,6 @@ export const patchRouter = createTRPCRouter({ ) .query(async ({ input, ctx }) => { let serverId: string | null = null; - let patchContent: string | undefined; if (input.type === "application") { const app = await findApplicationById(input.id); @@ -357,16 +356,6 @@ export const patchRouter = createTRPCRouter({ }); } serverId = app.serverId; - - // Check if patch exists for this file - const existingPatch = await findPatchByFilePath( - input.filePath, - input.id, - undefined, - ); - if (existingPatch?.enabled) { - patchContent = existingPatch.content; - } } else if (input.type === "compose") { const compose = await findComposeById(input.id); if ( @@ -379,27 +368,22 @@ export const patchRouter = createTRPCRouter({ }); } serverId = compose.serverId; - - // Check if patch exists for this file - const existingPatch = await findPatchByFilePath( - input.filePath, - undefined, - input.id, - ); - if (existingPatch?.enabled) { - patchContent = existingPatch.content; - } } else { throw new TRPCError({ code: "BAD_REQUEST", message: "Either applicationId or composeId must be provided", }); } + const existingPatch = await findPatchByFilePath( + input.filePath, + input.id, + input.type, + ); return await readPatchRepoFile( input.repoPath, input.filePath, - patchContent, + existingPatch?.enabled ? existingPatch?.content : undefined, serverId, ); }), @@ -461,7 +445,7 @@ export const patchRouter = createTRPCRouter({ const existingPatch = await findPatchByFilePath( input.filePath, input.id, - input.id, + input.type, ); if (existingPatch) { await deletePatch(existingPatch.patchId); @@ -473,22 +457,20 @@ export const patchRouter = createTRPCRouter({ const existingPatch = await findPatchByFilePath( input.filePath, input.id, - input.id, + input.type, ); if (existingPatch) { - // Update existing patch await updatePatch(existingPatch.patchId, { content: patchContent }); return { deleted: false, patchId: existingPatch.patchId }; } - // Create new patch const newPatch = await createPatch({ filePath: input.filePath, content: patchContent, enabled: true, - applicationId: input.id, - composeId: input.id, + applicationId: input.type === "application" ? input.id : undefined, + composeId: input.type === "compose" ? input.id : undefined, }); return { deleted: false, patchId: newPatch.patchId }; diff --git a/packages/server/src/services/patch.ts b/packages/server/src/services/patch.ts index 22d0bc8c0..095e9a9d1 100644 --- a/packages/server/src/services/patch.ts +++ b/packages/server/src/services/patch.ts @@ -76,23 +76,15 @@ export const findPatchesByComposeId = async (composeId: string) => { export const findPatchByFilePath = async ( filePath: string, - applicationId?: string, - composeId?: string, + id: string, + type: "application" | "compose", ) => { - if (applicationId) { - return await db.query.patch.findFirst({ - where: and( - eq(patch.filePath, filePath), - eq(patch.applicationId, applicationId), - ), - }); - } - if (composeId) { - return await db.query.patch.findFirst({ - where: and(eq(patch.filePath, filePath), eq(patch.composeId, composeId)), - }); - } - return null; + return await db.query.patch.findFirst({ + where: + type === "application" + ? and(eq(patch.filePath, filePath), eq(patch.applicationId, id)) + : and(eq(patch.filePath, filePath), eq(patch.composeId, id)), + }); }; export const updatePatch = async (patchId: string, data: Partial) => {