Skip to content

Commit

Permalink
fix: Integration edit google (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
adityachoudhari26 authored Sep 5, 2024
1 parent b395a43 commit 7927702
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { TbDots } from "react-icons/tb";

import type { TargetProvider, TargetProviderGoogle } from "@ctrlplane/db/schema";
import {
AlertDialog,
AlertDialogAction,
Expand All @@ -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 (
<DropdownMenu>
Expand All @@ -43,7 +49,17 @@ export const ProviderActionsDropdown: React.FC<{ providerId: string }> = ({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Edit</DropdownMenuItem>
{provider.googleConfig != null && (
<UpdateGoogleProviderDialog
providerId={provider.id}
name={provider.name}
projectIds={provider.googleConfig.projectIds}
>
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
Edit
</DropdownMenuItem>
</UpdateGoogleProviderDialog>
)}
<AlertDialog>
<AlertDialogTrigger asChild>
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() })),
});
Expand All @@ -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({
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<Dialog
open={open}
onOpenChange={(o) => {
setOpen(o);
if (!o) form.reset();
}}
>
<DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent>
<Form {...form}>
<form onSubmit={onSubmit} className="space-y-3">
<DialogHeader>
<DialogTitle>Configure Google Provider</DialogTitle>
<DialogDescription>
Google provider allows you to configure and import GKE clusters
from google.
</DialogDescription>
</DialogHeader>

<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Provider Name</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<div>
{fields.map((field, index) => (
<FormField
control={form.control}
key={field.id}
name={`projectIds.${index}.value`}
render={({ field }) => (
<FormItem>
<FormLabel className={cn(index !== 0 && "sr-only")}>
Google Projects
</FormLabel>
<FormControl>
<div className="flex items-center gap-2">
<Input placeholder="my-gcp-project-id" {...field} />

{fields.length > 1 && (
<Button
type="button"
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => remove(index)}
>
<TbX className="h-4 w-4" />
</Button>
)}
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
))}
<Button
type="button"
variant="outline"
size="sm"
className="mt-4"
onClick={() => append({ value: "" })}
>
Add Project
</Button>
</div>

<DialogFooter>
<Button
type="submit"
disabled={
form.formState.isSubmitting || !form.formState.isDirty
}
>
Update
</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default function TargetProvidersPage({
</TooltipProvider>
</TableCell>
<TableCell className="text-right">
<ProviderActionsDropdown providerId={provider.id} />
<ProviderActionsDropdown provider={provider} />
</TableCell>
</TableRow>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

import { SiGooglecloud } from "react-icons/si";

import { Card } from "@ctrlplane/ui/card";

export default function GoogleIntegrationPage() {
return (
<div className="flex flex-col gap-12">
<div className="flex items-center gap-4">
<SiGooglecloud className="h-14 w-14 text-red-400" />
<div className="flex flex-col gap-1">
<h1 className="text-3xl font-bold">Google</h1>
<p className="text-sm text-muted-foreground">
Sync deployment targets, trigger google workflows and more.
</p>
</div>
</div>

<Card className="flex items-center justify-between rounded-md p-4">
<div className="space-y-1">
<h2 className="text-lg font-semibold">Google Cloud</h2>
<p className="text-sm text-muted-foreground">
Sync deployment targets, trigger google workflows and more.
</p>
</div>
</Card>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ export default function IntegrationLayout({
const router = useRouter();
const { workspaceSlug } = params;
return (
<div className="flex flex-col gap-4">
<Button
variant="ghost"
onClick={() =>
router.push(`/${workspaceSlug}/settings/workspace/integrations`)
}
className="flex w-fit items-center gap-2"
>
<TbArrowLeft className="h-4 w-4" /> Integrations
</Button>
{children}
<div className="flex justify-center">
<div className="flex max-w-3xl flex-col gap-4">
<Button
variant="ghost"
onClick={() =>
router.push(`/${workspaceSlug}/settings/workspace/integrations`)
}
className="flex w-fit items-center gap-2"
>
<TbArrowLeft className="h-4 w-4" /> Integrations
</Button>
{children}
</div>
</div>
);
}
Loading

0 comments on commit 7927702

Please sign in to comment.