From 7927702983dc94044467c4ca459e61a996da7d1d Mon Sep 17 00:00:00 2001 From: Aditya Choudhari <48932219+adityachoudhari26@users.noreply.github.com> Date: Wed, 4 Sep 2024 22:55:31 -0700 Subject: [PATCH] fix: Integration edit google (#14) --- .../ProviderActionsDropdown.tsx | 26 ++- .../{ => google}/GoogleDialog.tsx | 4 +- .../google/UpdateGoogleProviderDialog.tsx | 158 ++++++++++++++++++ .../target-providers/integrations/page.tsx | 2 +- .../(targets)/target-providers/page.tsx | 2 +- .../(integration)/google/page.tsx | 30 ++++ .../integrations/(integration)/layout.tsx | 24 +-- .../workspace/integrations/page.tsx | 54 +++--- .../(settings)/workspace/overview/page.tsx | 13 +- packages/api/src/router/target.ts | 110 ++++++++---- packages/db/src/schema/target-provider.ts | 2 +- 11 files changed, 337 insertions(+), 88 deletions(-) rename apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/{ => google}/GoogleDialog.tsx (96%) create mode 100644 apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/UpdateGoogleProviderDialog.tsx create mode 100644 apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/google/page.tsx diff --git a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/ProviderActionsDropdown.tsx b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/ProviderActionsDropdown.tsx index 64aa0e11..71abb394 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/ProviderActionsDropdown.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/ProviderActionsDropdown.tsx @@ -2,6 +2,7 @@ import { TbDots } from "react-icons/tb"; +import type { TargetProvider, TargetProviderGoogle } from "@ctrlplane/db/schema"; import { AlertDialog, AlertDialogAction, @@ -22,17 +23,22 @@ import { } from "@ctrlplane/ui/dropdown-menu"; import { api } from "~/trpc/react"; +import { UpdateGoogleProviderDialog } from "./integrations/google/UpdateGoogleProviderDialog"; -export const ProviderActionsDropdown: React.FC<{ providerId: string }> = ({ - providerId, -}) => { +type Provider = TargetProvider & { + googleConfig: TargetProviderGoogle | null; +}; + +export const ProviderActionsDropdown: React.FC<{ + provider: Provider; +}> = ({ provider }) => { const utils = api.useUtils(); const deleteProvider = api.target.provider.delete.useMutation({ onSuccess: () => utils.target.provider.byWorkspaceId.invalidate(), }); const handleDelete = (deleteTargets: boolean) => - deleteProvider.mutate({ providerId, deleteTargets }); + deleteProvider.mutate({ providerId: provider.id, deleteTargets }); return ( @@ -43,7 +49,17 @@ export const ProviderActionsDropdown: React.FC<{ providerId: string }> = ({ - Edit + {provider.googleConfig != null && ( + + e.preventDefault()}> + Edit + + + )} e.preventDefault()}> diff --git a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/GoogleDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/GoogleDialog.tsx similarity index 96% rename from apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/GoogleDialog.tsx rename to apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/GoogleDialog.tsx index 689ec6dc..9ad7ba7b 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/GoogleDialog.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/GoogleDialog.tsx @@ -28,7 +28,7 @@ import { Input } from "@ctrlplane/ui/input"; import { api } from "~/trpc/react"; -const createGoogleSchema = z.object({ +export const createGoogleSchema = z.object({ name: z.string(), projectIds: z.array(z.object({ value: z.string() })), }); @@ -52,7 +52,7 @@ export const GoogleDialog: React.FC<{ children: React.ReactNode }> = ({ const router = useRouter(); const utils = api.useUtils(); - const create = api.target.provider.managed.google.useMutation(); + const create = api.target.provider.managed.google.create.useMutation(); const onSubmit = form.handleSubmit(async (data) => { if (workspace.data == null) return; await create.mutateAsync({ diff --git a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/UpdateGoogleProviderDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/UpdateGoogleProviderDialog.tsx new file mode 100644 index 00000000..1cdb1077 --- /dev/null +++ b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/google/UpdateGoogleProviderDialog.tsx @@ -0,0 +1,158 @@ +import { useState } from "react"; +import { useParams } from "next/navigation"; +import { TbX } from "react-icons/tb"; + +import { cn } from "@ctrlplane/ui"; +import { Button } from "@ctrlplane/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@ctrlplane/ui/dialog"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, + useFieldArray, + useForm, +} from "@ctrlplane/ui/form"; +import { Input } from "@ctrlplane/ui/input"; + +import { api } from "~/trpc/react"; +import { createGoogleSchema } from "./GoogleDialog"; + +export const UpdateGoogleProviderDialog: React.FC<{ + providerId: string; + name: string; + projectIds: string[]; + children: React.ReactNode; +}> = ({ providerId, name, projectIds, children }) => { + const { workspaceSlug } = useParams<{ workspaceSlug: string }>(); + const workspace = api.workspace.bySlug.useQuery(workspaceSlug); + const form = useForm({ + schema: createGoogleSchema, + defaultValues: { name, projectIds: projectIds.map((p) => ({ value: p })) }, + mode: "onChange", + }); + + const utils = api.useUtils(); + const update = api.target.provider.managed.google.update.useMutation(); + const onSubmit = form.handleSubmit(async (data) => { + if (workspace.data == null) return; + await update.mutateAsync({ + ...data, + targetProviderId: providerId, + config: { projectIds: data.projectIds.map((p) => p.value) }, + }); + await utils.target.provider.byWorkspaceId.invalidate(); + setOpen(false); + }); + + const { fields, append, remove } = useFieldArray({ + control: form.control, + name: "projectIds", + }); + + const [open, setOpen] = useState(false); + + return ( + { + setOpen(o); + if (!o) form.reset(); + }} + > + {children} + +
+ + + Configure Google Provider + + Google provider allows you to configure and import GKE clusters + from google. + + + + ( + + Provider Name + + + + + + )} + /> + +
+ {fields.map((field, index) => ( + ( + + + Google Projects + + +
+ + + {fields.length > 1 && ( + + )} +
+
+ +
+ )} + /> + ))} + +
+ + + + + + +
+
+ ); +}; diff --git a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/page.tsx b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/page.tsx index 00fb7034..93be14eb 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/integrations/page.tsx @@ -12,7 +12,7 @@ import { cn } from "@ctrlplane/ui"; import { Button } from "@ctrlplane/ui/button"; import { Card } from "@ctrlplane/ui/card"; -import { GoogleDialog } from "./GoogleDialog"; +import { GoogleDialog } from "./google/GoogleDialog"; const Badge: React.FC<{ className?: string; children?: React.ReactNode }> = ({ className, diff --git a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/page.tsx b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/page.tsx index 03b8237f..425b3369 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(targets)/target-providers/page.tsx @@ -91,7 +91,7 @@ export default function TargetProvidersPage({ - + ))} diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/google/page.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/google/page.tsx new file mode 100644 index 00000000..095e3bb9 --- /dev/null +++ b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/google/page.tsx @@ -0,0 +1,30 @@ +"use client"; + +import { SiGooglecloud } from "react-icons/si"; + +import { Card } from "@ctrlplane/ui/card"; + +export default function GoogleIntegrationPage() { + return ( +
+
+ +
+

Google

+

+ Sync deployment targets, trigger google workflows and more. +

+
+
+ + +
+

Google Cloud

+

+ Sync deployment targets, trigger google workflows and more. +

+
+
+
+ ); +} diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/layout.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/layout.tsx index 98b9f9c8..075237de 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/layout.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/(integration)/layout.tsx @@ -15,17 +15,19 @@ export default function IntegrationLayout({ const router = useRouter(); const { workspaceSlug } = params; return ( -
- - {children} +
+
+ + {children} +
); } diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/page.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/page.tsx index 264e94f3..eea2030a 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/integrations/page.tsx @@ -1,34 +1,32 @@ import Link from "next/link"; -import { SiGithub } from "react-icons/si"; +import { SiGithub, SiGooglecloud } from "react-icons/si"; -import { Button } from "@ctrlplane/ui/button"; import { Card } from "@ctrlplane/ui/card"; export const metadata = { title: "Integrations" }; const IntegrationCard: React.FC<{ + integration: string; + workspaceSlug: string; children: React.ReactNode; -}> = ({ children }) => ( - - {children} +}> = ({ children, integration, workspaceSlug }) => ( + + + {children} + ); const IntegrationContent: React.FC<{ children: React.ReactNode }> = ({ children, -}) =>
{children}
; - -const IntegrationActionButton: React.FC<{ - children: React.ReactNode; -}> = ({ children }) => ( - -); +}) =>
{children}
; const IntegrationHeading: React.FC<{ children: React.ReactNode }> = ({ children, -}) =>
{children}
; +}) =>
{children}
; export default function IntegrationsPage({ params, @@ -38,7 +36,7 @@ export default function IntegrationsPage({ const { workspaceSlug } = params; return ( -
+

Integrations

@@ -47,23 +45,29 @@ export default function IntegrationsPage({

- + - -
GitHub Bot
+ + GitHub
-

+

Grant our account the correct permissions and we will manage running the target provider for you.

+
- - Configure - + + + + + Google + +

+ Sync deployment targets, trigger google workflows and more. +

+
diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/overview/page.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/overview/page.tsx index 255486fa..0e1aa9fa 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/overview/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/(settings)/workspace/overview/page.tsx @@ -17,6 +17,7 @@ export default function OverviewPage({ }: { params: { workspaceSlug: string }; }) { + const { workspaceSlug } = params; return (
@@ -45,7 +46,7 @@ export default function OverviewPage({
- + @@ -73,7 +74,7 @@ export default function OverviewPage({
- + @@ -100,7 +101,7 @@ export default function OverviewPage({
- + @@ -133,7 +134,7 @@ export default function OverviewPage({