From 68d2e73e7a6a1d7f64fbf6cdbdf34d8cb8e72e20 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:00:10 -0600 Subject: [PATCH] feat: add test connection github --- .../git/github/edit-github-provider.tsx | 154 ++++++++++++++++++ .../settings/git/show-git-providers.tsx | 6 + apps/dokploy/server/api/routers/github.ts | 28 +++- .../server/api/services/git-provider.ts | 44 ++--- apps/dokploy/server/api/services/github.ts | 17 ++ apps/dokploy/server/db/schema/github.ts | 8 + 6 files changed, 225 insertions(+), 32 deletions(-) create mode 100644 apps/dokploy/components/dashboard/settings/git/github/edit-github-provider.tsx diff --git a/apps/dokploy/components/dashboard/settings/git/github/edit-github-provider.tsx b/apps/dokploy/components/dashboard/settings/git/github/edit-github-provider.tsx new file mode 100644 index 00000000..455369a2 --- /dev/null +++ b/apps/dokploy/components/dashboard/settings/git/github/edit-github-provider.tsx @@ -0,0 +1,154 @@ +import { GithubIcon } from "@/components/icons/data-tools-icons"; +import { AlertBlock } from "@/components/shared/alert-block"; +import { Button } from "@/components/ui/button"; +import { CardContent } from "@/components/ui/card"; +import { + Dialog, + DialogContent, + 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"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { Edit } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; + +const Schema = z.object({ + name: z.string().min(1, { + message: "Name is required", + }), +}); + +type Schema = z.infer; + +interface Props { + githubId: string; +} + +export const EditGithubProvider = ({ githubId }: Props) => { + const { data: github } = api.github.one.useQuery( + { + githubId, + }, + { + enabled: !!githubId, + }, + ); + const utils = api.useUtils(); + const [isOpen, setIsOpen] = useState(false); + const { mutateAsync, error, isError } = api.github.update.useMutation(); + const { mutateAsync: testConnection, isLoading } = + api.github.testConnection.useMutation(); + const form = useForm({ + defaultValues: { + name: "", + }, + resolver: zodResolver(Schema), + }); + + useEffect(() => { + form.reset({ + name: github?.gitProvider.name || "", + }); + }, [form, isOpen]); + + const onSubmit = async (data: Schema) => { + await mutateAsync({ + githubId, + name: data.name || "", + gitProviderId: github?.gitProviderId || "", + }) + .then(async () => { + await utils.gitProvider.getAll.invalidate(); + toast.success("Github updated successfully"); + setIsOpen(false); + }) + .catch(() => { + toast.error("Error to update Github"); + }); + }; + + return ( + + + + + + + + Update Github Provider + + + + {isError && {error?.message}} +
+ + +
+ ( + + Name + + + + + + )} + /> + +
+ + +
+
+
+
+ +
+
+ ); +}; diff --git a/apps/dokploy/components/dashboard/settings/git/show-git-providers.tsx b/apps/dokploy/components/dashboard/settings/git/show-git-providers.tsx index 9f0aad7a..798eff6c 100644 --- a/apps/dokploy/components/dashboard/settings/git/show-git-providers.tsx +++ b/apps/dokploy/components/dashboard/settings/git/show-git-providers.tsx @@ -15,6 +15,7 @@ import { useUrl } from "@/utils/hooks/use-url"; import { EditBitbucketProvider } from "./bitbucket/edit-bitbucket-provider"; import { EditGitlabProvider } from "./gitlab/edit-gitlab-provider"; import { formatDate } from "date-fns"; +import { EditGithubProvider } from "./github/edit-github-provider"; export const ShowGitProviders = () => { const { data } = api.gitProvider.getAll.useQuery(); @@ -153,6 +154,11 @@ export const ShowGitProviders = () => { gitlabId={gitProvider.gitlab.gitlabId} /> )} + {isGithub && haveGithubRequirements && ( + + )} { @@ -41,9 +47,25 @@ export const githubRouter = createTRPCRouter({ return filtered; }), + testConnection: protectedProcedure .input(apiFindOneGithub) - .query(async ({ input }) => { - return await findGithubById(input.githubId); + .mutation(async ({ input }) => { + try { + const result = await getGithubRepositories(input.githubId); + return `Found ${result.length} repositories`; + } catch (err) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: err instanceof Error ? err?.message : `Error: ${err}`, + }); + } + }), + update: protectedProcedure + .input(apiUpdateGithub) + .mutation(async ({ input }) => { + await updateGitProvider(input.gitProviderId, { + name: input.name, + }); }), }); diff --git a/apps/dokploy/server/api/services/git-provider.ts b/apps/dokploy/server/api/services/git-provider.ts index 66aed3ac..b73aeeda 100644 --- a/apps/dokploy/server/api/services/git-provider.ts +++ b/apps/dokploy/server/api/services/git-provider.ts @@ -3,35 +3,7 @@ import { type apiCreateGithub, github, gitProvider } from "@/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; -export const createGithub = async (input: typeof apiCreateGithub._type) => { - return await db.transaction(async (tx) => { - const newGitProvider = await tx - .insert(gitProvider) - .values({ - providerType: "github", - authId: input.authId, - name: input.name, - }) - .returning() - .then((response) => response[0]); - - if (!newGitProvider) { - throw new TRPCError({ - code: "BAD_REQUEST", - message: "Error to create the git provider", - }); - } - - return await tx - .insert(github) - .values({ - ...input, - gitProviderId: newGitProvider?.gitProviderId, - }) - .returning() - .then((response) => response[0]); - }); -}; +export type GitProvider = typeof gitProvider.$inferSelect; export const removeGitProvider = async (gitProviderId: string) => { const result = await db @@ -41,3 +13,17 @@ export const removeGitProvider = async (gitProviderId: string) => { return result[0]; }; + +export const updateGitProvider = async ( + gitProviderId: string, + input: Partial, +) => { + return await db + .update(gitProvider) + .set({ + ...input, + }) + .where(eq(gitProvider.gitProviderId, gitProviderId)) + .returning() + .then((response) => response[0]); +}; diff --git a/apps/dokploy/server/api/services/github.ts b/apps/dokploy/server/api/services/github.ts index 14980185..0f0f0493 100644 --- a/apps/dokploy/server/api/services/github.ts +++ b/apps/dokploy/server/api/services/github.ts @@ -37,6 +37,9 @@ export const createGithub = async (input: typeof apiCreateGithub._type) => { export const findGithubById = async (githubId: string) => { const githubProviderResult = await db.query.github.findFirst({ where: eq(github.githubId, githubId), + with: { + gitProvider: true, + }, }); if (!githubProviderResult) { @@ -56,3 +59,17 @@ export const haveGithubRequirements = (github: Github) => { github?.githubInstallationId ); }; + +export const updateGithub = async ( + githubId: string, + input: Partial, +) => { + return await db + .update(github) + .set({ + ...input, + }) + .where(eq(github.githubId, githubId)) + .returning() + .then((response) => response[0]); +}; diff --git a/apps/dokploy/server/db/schema/github.ts b/apps/dokploy/server/db/schema/github.ts index 487a74df..c3809eed 100644 --- a/apps/dokploy/server/db/schema/github.ts +++ b/apps/dokploy/server/db/schema/github.ts @@ -39,6 +39,8 @@ export const apiCreateGithub = createSchema.extend({ githubPrivateKey: z.string().optional(), githubWebhookSecret: z.string().nullable(), gitProviderId: z.string().optional(), + name: z.string().min(1), + authId: z.string().min(1), }); export const apiFindGithubBranches = z.object({ @@ -52,3 +54,9 @@ export const apiFindOneGithub = createSchema githubId: z.string().min(1), }) .pick({ githubId: true }); + +export const apiUpdateGithub = createSchema.extend({ + githubId: z.string().min(1), + name: z.string().min(1), + gitProviderId: z.string().min(1), +});